Это не работает, потому что при создании массива типа BaseClass компилятор ничего не знает о методе print()
. Они просто представлены в ваших 2 подклассах.
Представьте, что у вас есть другой подкласс под названием E
(также расширяющий базовый класс), который не имеет функции print()
. Теперь назначьте объект E одному из мест в myarr
. Пока здесь все будет работать нормально. Теперь, когда вы попытаетесь вызвать метод print()
, компилятор не будет знать, что делать. Вот почему компилятор не может найти print () и не хочет «интерпретировать» ваш код.
Теперь для решения этой проблемы есть 2 возможности. Если вам нужен print()
-метод в каждом подклассе, вы можете просто создать один абстрактный метод:
public abstract class BaseClass {
public BaseClass() {
// Some Constructor Work
}
// This tells the compiler there is a print()-method in every subclass because it must be overridden
public abstract void print();
}
Теперь в ваших подклассах (я просто делаю один для подтверждения концепции:)):
public class SubClass extends BaseClass {
public SubClass() {
// Do Constructor Work if necessary
}
// I would highly suggest you also use this annotation because it helps you
// identifying overridden methods (but it is not obligatory to use)
@Override
public void print() {
System.out.println("Hello from SubClass");
}
}
Теперь у вас в главном:
public static void main(String[] args) {
// Init Array
BaseClass[] myarr = new BaseClass[4];
myarr[0] = new SubClass();
myarr[1] = new OtherSubClass();
// and so on... I think you get the gist
// Now execute print()
myarr[0].print(); // This works perfectly now.
}
Теперь возможность 2, которая в зависимости от вашего варианта использования может быть единственной работающей (хотя я настоятельно рекомендую использовать метод, показанный ранее, поскольку здесь вы должны быть На 100% уверен, что ClassType вашего объекта) намного небезопаснее, и вы должны знать, что вы делаете, или вы получаете ошибки (и никто не любит ошибки правильно? :)): Используйте Casting.
public static void main(String[] args) { // Note I will be using "your" classes here again
// Array Init...
BaseClass[] myarr = new BaseClass[10];
// Assign blabla
myarr[0] = new C();
myarr[1] = new D();
((C) myarr[0]).print(); // Casting to C-Type which has a print()
}
Это будет в основном, сообщаем компилятору (и JVM): «Эй, не волнует, какой тип у этого объекта. Просто предположим, что это будет C -Тип!» Я думаю, вы начинаете понимать, в чем может быть проблема. Если компилятор хочет прочитать C -Тип, но вместо этого получает D-тип или E-тип, он не знает, что делать -> Ошибка.
Надеюсь, я мог бы помочь вам:)
РЕДАКТИРОВАТЬ:
Ах, и обратите внимание, что добавив в класс модификатор abstract, вы не можете больше создавать объект этого класса, только из соответствующих дочерних классов. Вот почему я также хотел дать вам возможность 2, так как это более универсально.