Animal
- базовый класс. Если вы расширили Animal
, вы можете добавить дополнительные методы и переменные экземпляра в этот класс, что вы на самом деле сделали правильно.
Как только вы создадите экземпляр дочернего класса (класса, который расширяет базовый класс, например: * 1005)*) но назначив его типу базового класса (Animal
), вы можете вызывать только доступные там методы, т. е. в вашем случае вы можете вызывать только методы, объявленные в классе Animal
.
Предположим, у вас есть класс Animal
:
public class Animal {
public void makeSound() {
System.out.println("Default sound");
}
}
Теперь вы создаете класс Cat
, который расширяет Animal
:
public class Cat extends Animal {
private int catProperty = 5;
//Override method of base class
public void makeSound() {
System.out.println("Meow");
}
public int getCatProperty(){
return this.catProperty;
}
}
Другой класс с именем Dog
, который расширяется Animal
:
public class Dog extends Animal {
private int dogProperty = 8;
//Override method of base class
public void makeSound() {
System.out.println("Woof");
}
public int getDogProperty(){
return this.dogProperty;
}
}
Поскольку Animal
является базовым классом, теперь вы можете создать array of type Animal
, который содержит Cats
и Dogs
.
Animal[] animals = new Animal[2];
animals[0] = new Cat();
animals[1] = new Dog();
for (Animal animal : animals) {
animal.makeSound();
}
Каждый из animals
(Cat
и Dog
) теперь будет печатать правильный звук. Если вам действительно нужно вызвать специфичный для дочернего класса метод , вам нужно привести объект обратно к экземпляру этого дочернего класса . В этом случае вы должны быть уверены в том, какого типа является дочерний класс.
Например:
for (Animal animal : animals) {
// Calls overriden method
animal.makeSound();
// This is illegal. Method getCatProperty is not declared in Animal
animal.getCatProperty();
// This is illegal. Method getDogProperty is not declared in Animal class
animal.getDogProperty();
/*
* IF YOU HAVE TO CALL CHILD CLASS SPECIFIC METHODS, DO IT LIKE THIS:
*/
// Checks if animal is of type Cat
if (animal instanceof Cat) {
// Casts animal to instance of Cat
Cat cat = (Cat) animal;
// Calls specific Cat instance method
System.out.println(cat.getCatProperty());
}
// Checks if animal is of type Dog
if (animal instanceof Dog) {
// Casts animal to instance of Dog
Dog dog = (Dog) animal;
// Calls specific Dog instance method
System.out.println(dog.getDogProperty());
}
}
Так же, как sidenote: Если вы не планируете напрямую создавать экземпляры Animal (Animal a = new Animal()
), вы должны объявить сам класс и методы, которые должны быть переопределены дочерними классами, как abstract
.
public abstract class Animal {
public abstract void makeSound();
}
Кроме того, в случае, если в базовом классе есть только методы и нет переменных экземпляра, которые должныбыть доступным для дочерних классов, вероятно, лучше использовать интерфейс вместо (abstract
) класса.
public interface Animal {
public abstract void makeSound();
}
Интерфейс должен быть implemented
(не extended
) конкретнымкласс.
public class Cat implements Animal {
public void makeSound() {
System.out.println("Meow");
}
}
Надеюсь, это поможет!