Как вызвать подкласс как тип суперкласса

В настоящее время я изучаю наследование, и у меня возникли проблемы с пониманием концепции. Для следующего кода кто-то может сказать мне, почему я не могу объявить подкласс типа 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 Компилятор не знает, откуда появился этот метод, и поэтому выдает ошибку времени компиляции.

Надеюсь, поможет!

Другие вопросы по тегам