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

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

person barapapupi    schedule 27.09.2014    source источник


Ответы (6)


Вы назначаете объект подкласса переменной типа суперкласса (т. е. выполняется повышение уровня), это нормально. Но когда вы это делаете, доступны только методы суперкласса. Поэтому, чтобы получить доступ к методам подкласса, выполните приведение к его типу подкласса. например.

    Superclass[] X = new Superclass[2];
    X[0] = new Subclass();
    ((Subclass) X[0]).setB("hello");
    ((Subclass) X[0]).display();
person Harish Narayan    schedule 27.09.2014

Самое интересное здесь заключается в том, что всякий раз, когда вы вызываете какой-либо метод для ссылки, этот метод должен присутствовать в объявлении его класса.

Метод может быть вызван или нет, определяется ссылочным типом, но какой экземпляр реализации должен вызываться, определяется типом его объекта.

поскольку у вас нет метода setB() в SuperClass, компилятор не знает, откуда взялся этот метод, и поэтому выдает ошибку времени компиляции.

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

person Vihar    schedule 27.09.2014

Переименуйте setB() в своем подклассе в setA(), добавьте функцию display() в свой суперкласс и вызовите setA() в своем подклассе как X[0].setA("hello");, и вы увидите, как это работает.

person SylvainL    schedule 27.09.2014

Измените свой код следующим образом — замените 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)
    }
}
person sberezin    schedule 27.09.2014

вы пытаетесь присвоить объект типа подкласса его объекту типа суперкласса X[0].

Таким образом, он не показывает никаких ошибок при его назначении. Но вам разрешено вызывать в подклассе те методы, которые имеют то же имя, что и в суперклассе.

Например

Если вы переименуете setB() в setA(), вы сможете найти ожидаемый результат, но не сможете вызвать setB()

Теперь попробуйте назначить myB=X[0]; и запустите

Вы получите эту ошибку: Исключение в потоке "основной" java.lang.NullPointerException

Теперь, если вы создадите новый объект подкласса, то есть подкласса subc=new Subclass();

и попробуйте назначить X[0] subc, subc=X[0]; вы получите эту ошибку, несовместимый тип (требуется подкласс, найден суперкласс)

person Md Rashedul Hoque Bhuiyan    schedule 27.09.2014

ваша переменная X имеет тип суперкласса, поэтому вы можете получить доступ только к видимым методам и атрибутам в этом классе или в его суперклассах (суперклассы суперкласса, но не его подклассы). Проблема, почему вы думаете, что можете вызвать метод setB(), заключается в том, что вы видите тип объекта, который вы назначаете Superclass[] X, который является новым Superclass[2], так что же происходит, когда вы получаете ссылку на такой объект в качестве атрибута в методе? вы даже не знаете, кто это вызывает, какие методы его подклассов вы можете угадать и вызвать, если у него даже есть подклассы? вы не можете

person Curcuma_    schedule 27.09.2014