Как вызвать подкласс как тип суперкласса
В настоящее время я изучаю наследование, и у меня возникли проблемы с пониманием концепции. Для следующего кода кто-то может сказать мне, почему я не могу объявить подкласс типа Superclass?
public class Test{
public static void main(String[] args){
Superclass myA = new Superclass();
Superclass myB = new Subclass();
}
public class Superclass{
private string a;
public Superclass()
{
a="";
}
public void setA(String userA)
{
a = userA;
}
}
public class Subclass extends Superclass{
private String b;
public Subclass()
{
b = "";
}
public void setB(String userB)
{
b = userB;
}
public void display()
{
System.out.print(b)
}
}
myA не доставляет мне проблем, но myB делает. Я хочу создать массив, скажем, суперкласса, но я хочу иметь возможность использовать подкласс. Что-то вроде этого
Superclass[] X = new Superclass[2];
x[0] = new Subclass();
X[0].setB("hello");
X[0].display();
6 ответов
Вы назначаете объект подкласса переменной типа суперкласса (т. Е. Обновление выполняется), это хорошо. Но когда вы делаете это, доступны только методы суперкласса. Поэтому, чтобы получить доступ к методам подкласса, пожалуйста, сделайте downcast до его типа подкласса. например.
Superclass[] X = new Superclass[2];
X[0] = new Subclass();
((Subclass) X[0]).setB("hello");
((Subclass) X[0]).display();
Переименовывать setB()
в вашем подклассе как setA()
, добавьте функцию display()
в свой суперкласс и позвоните setA()
в вашем подклассе как X[0].setA("hello");
и вы увидите, как это работает.
Измените свой код следующим образом - измените setA() и setB() на set() - и ваш код будет работать. Поведение называется полиморфизмом и является одной из основных концепций ОО-программирования.
public class Superclass{
private string a;
public Superclass()
{
a="";
}
public void set(String userA)
{
a = userA;
}
}
public class Subclass extends Superclass{
private String b;
public Subclass()
{
b = "";
}
@override
public void set(String userB)
{
b = userB;
}
public void display()
{
System.out.print(b)
}
}
Вы пытаетесь присвоить объект типа подкласса его объекту типа суперкласса X[0].
Таким образом, он не показывает ошибки при его назначении. Но вы можете вызывать эти методы в подклассе, имя которого совпадает с именем в суперклассе.
Например
Если вы переименуете setB() в setA (), вы можете найти ожидаемый результат, но не можете вызвать setB()
Теперь попробуйте назначить myB=X[0]; и беги
Вы получите эту ошибку: Исключение в потоке "main" java.lang.NullPointerException
Теперь, если вы создаете новый объект Subclass, т.е. Subclass subc = new Subclass ();
и попробуйте назначить X [0] для subc, subc=X[0]; Вы получите эту ошибку, несовместимый тип (требуемый подкласс, найденный суперкласс)
Ваша переменная X имеет тип Superclass, так что вы можете получить доступ только к видимым методам и атрибутам в этом классе или в его суперклассах (суперклассы суперкласса, но не его подклассы). Проблема, почему вы думаете, что можете позвонить setB()
Метод заключается в том, что вы видите тип объекта, который вы назначаете Superclass[] X
что нового Superclass[2]
Итак, что происходит, когда вы получаете ссылку на такой объект как атрибут в методе? вы даже не знаете, что это вызывающие, какие методы его подклассов вы можете угадать и вызвать, если у него даже есть подклассы? ты не можешь
Главное удовольствие здесь - всякий раз, когда вы вызываете какой-либо метод по ссылке, этот метод должен присутствовать в объявлении класса.
Метод может быть вызван или нет, определяется по ссылочному типу, но выбор экземпляра реализации определяется по типу объекта.
так как у вас нет setB()
метод в SuperClass
Компилятор не знает, откуда появился этот метод, и поэтому выдает ошибку времени компиляции.
Надеюсь, поможет!