Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Наследование в Java
В Java есть несколько способов наследовать функциональность от одного класса к другому. Это основной механизм переиспользования кода и полиморфизма.
1. Классическое наследование (extends)
Мост простой и распространённый способ:
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating");
}
}
// Dog наследует всё от Animal
public class Dog extends Animal {
public Dog(String name) {
super(name); // вызов конструктора родителя
}
// Переопределяем (override) метод
@Override
public void eat() {
System.out.println(name + " is eating bones");
}
// Добавляем свой метод
public void bark() {
System.out.println("Woof!");
}
}
// Использование
Dog dog = new Dog("Rex");
dog.eat(); // Rex is eating bones
dog.bark(); // Woof!
Ключевые моменты:
- Класс может наследовать только от одного класса (single inheritance)
- Используется ключевое слово
extends super()вызывает конструктор/методы родителя@Overrideаннотация помечает переопределениеprotectedчлены видны подклассам
2. Наследование интерфейсов (implements)
Класс может реализовать один или несколько интерфейсов:
interface Eatable {
void eat();
}
interface Sleepable {
void sleep();
}
public class Dog extends Animal implements Eatable, Sleepable {
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping");
}
}
Множественное наследование интерфейсов:
- Класс может реализовать сколько угодно интерфейсов
- Интерфейсы задают контракт (что должно быть реализовано)
- Решает проблему множественного наследования
3. Наследование интерфейсов интерфейсами
Интерфейсы могут наследовать от других интерфейсов:
interface Animal {
void eat();
}
interface Pet extends Animal {
void play();
}
public class Dog implements Pet {
@Override
public void eat() { System.out.println("Eating"); }
@Override
public void play() { System.out.println("Playing"); }
}
4. Абстрактные классы
Промежуточный уровень между классом и интерфейсом:
public abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
// Абстрактный метод (обязателен для реализации)
public abstract void makeSound();
// Обычный метод
public void sleep() {
System.out.println(name + " is sleeping");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
Особенности абстрактных классов:
- Не могут быть инстанцированы (
new Animal()— ошибка) - Могут содержать поля, конструкторы, обычные методы
- Обеспечивают состояние и поведение
- Подходят для связанных классов
5. Иерархия наследования
Много уровней наследования:
class Animal {
public void eat() { System.out.println("Eating"); }
}
class Mammal extends Animal {
public void warmBlooded() { System.out.println("Warm blooded"); }
}
class Dog extends Mammal {
public void bark() { System.out.println("Woof"); }
}
// Dog наследует: eat() от Animal, warmBlooded() от Mammal, bark() свой
Dog dog = new Dog();
dog.eat(); // OK
dog.warmBlooded(); // OK
dog.bark(); // OK
6. Комбинированное наследование
public class Dog extends Animal implements Pet, Comparable<Dog> {
@Override
public void play() { System.out.println("Playing"); }
@Override
public int compareTo(Dog other) {
return this.name.compareTo(other.name);
}
}
7. Полиморфизм через наследование
List<Animal> animals = new ArrayList<>();
animals.add(new Dog("Rex"));
animals.add(new Cat("Whiskers"));
// Полиморфизм: вызываем переопределённые методы
for (Animal animal : animals) {
animal.makeSound(); // каждый животное звучит по-своему
}
Правила и лучшие практики
Используй интерфейсы, когда:
- Нужна контрактная связь (что-то должно делать)
- Требуется множественное наследование
- Классы не связаны
Используй абстрактные классы, когда:
- Есть связанные классы
- Нужны protected/private члены
- Нужны конструкторы с параметрами
- Нужно состояние (поля)
Используй обычные классы, когда:
- Классы полностью реализованы
- Нет необходимости в абстракции
Эти механизмы позволяют строить гибкие и переиспользуемые архитектуры в Java.