Почему подкасс отвечает, когда идет вверх? - PullRequest
0 голосов
/ 01 октября 2019
interface Readable {
    public void printTitle();
}

class WebText implements Readable {
    public String title;

    public void printTitle(){
        System.out.println("This Webpage title is "+ title);
    }

    public void setTitle(String title){
        this.title = title;
    }
}

class Blog extends WebText {

    public void printTitle(){
        System.out.println("The Blog title is " + title);
    }
}

class ReadingTester{
    public static void main(String [] arg) {
        Blog b1 = new Blog();
        WebText b2 = new Blog();

        b1.setTitle("How to upcast");
        b2.setTitle("Dangers of upcasting");

        b1.printTitle();
        b2.printTitle();

    }
}

Приведенный выше код относится к домашнему заданию, над которым я работаю, но я действительно не уверен в том, что происходит. Когда я запускаю код, он выдает:

Название блога: Как выгружать

Заголовок блога: Опасности переката

Почему я запутался, почему? второй выводит «Заголовок блога» вместо «Заголовок этой страницы:». Поскольку b2 преобразуется в WebText, не должен ли этот класс отвечать? Все, что я нахожу в Интернете, говорит, что апкастинг безопасен, но является ли это примером того, когда это не так? Я очень запутался и был бы очень признателен, спасибо большое!

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Во время компиляции WebText b2 = new Blog(); проверяет, могут ли быть выполнены вызовы метода для b2. Он видит, что у блога есть и setTitle, и printTitle. Так что он относится к b2 как к блогу.

Если у вас был другой метод в блоге, скажем, printTwice(), и вы попытались вызвать b2.printTwice(), компилятор выдаст ошибку времени компиляции, поскольку он не может обработать объект WebText как объект Blog (поскольку b2 не может ссылаться на объект Blog)

1 голос
/ 01 октября 2019

printTitle in Blog переопределяет printTitle in WebText. Поскольку b2 на самом деле является экземпляром Blog во время выполнения, вызов printTitle вызовет тот в Blog, хотя во время компиляции b2 имеет тип WebText. Это разновидность полиморфизма .

Такое поведение на самом деле желательно, поскольку оно позволяет вам иметь переменную типа WebText, которая может хранить множество различных типов веб-страниц. тексты, включая блоги, новостные статьи и ответы на переполнение стека. Каждый из этих типов может распечатать свои заголовки по-своему. Этот пост может помочь вам понять, почему мы делаем это лучше .

Почему это называется безопасным?

Это безопасно, так какв том, что это не исключение. Это небезопасно, так как в b2.printTitle может не вызываться метод в WebText, но вы все равно не должны предполагать, что это в первую очередь, если только метод не является final.

...