Почему компилятор разрешает приведение предка к потомку?

 
 
 
Сообщения:53
public class InheritanceInitOrder {
    static class A {
        String a;
        A() {
            a = "a";
            System.out.println("a initialized");
            System.out.println("b=" + ((B)this).b);  //ВОТ ЗДЕСЬ
        }
    }

    static class B extends A {
        String b;
        B() {
            b = "b";
            System.out.println("b initialized");
            System.out.println("b=" + b);
        }
    }

    public static void main(String[] args) throws ClassNotFoundException {
        new B();
    }
}


В отмеченной строке объект класса A приводится к дочернему классу B. Разве так можно? Не могу понять!!!

Сидящих за твоим столом ты не спеши назвать Друзьями...

Их проверяют не вином.... А горем... помощью... годами....
Изменен:12 янв 2021 07:04
 
 
Сообщения:10017
Собсно только так и можно - приводить к типам дочерних классов и только. А как по-другому?
Там же по факту может быть объект класса B.

PS: не забывай форматировать код с помощью [code]
Изменен:11 янв 2021 14:33
 
 
Сообщения:53
Староверъ:
Собсно только так и можно - приводить к типам дочерних классов и только. А как по-другому?
Там же по факту может быть объект класса B.

PS: не забывай форматировать код с помощью [code]

но у предка же может не быть каких-то полей и методов потомка. обычно приводят потомка к предку

Сидящих за твоим столом ты не спеши назвать Друзьями...

Их проверяют не вином.... А горем... помощью... годами....
 
 
Сообщения:10017
Какой смысл потомка к предку приводить - у потомка и без приведения есть все методы от предка.
Fernandel:
но у предка же может не быть каких-то полей и методов потомка
Поэтому нужно точно знать что это за потомок. Например, сначала проверив его с помощью instanceof.

Если же мы приводим, а тип не тот - мы получим ClassCastException.
Изменен:11 янв 2021 14:40
 
 
Сообщения:53
Староверъ:
Какой смысл потомка к предку приводить - у потомка и без приведения есть все методы от предка.
Fernandel:
но у предка же может не быть каких-то полей и методов потомка
Поэтому нужно точно знать что это за потомок. Например, сначала проверив его с помощью instanceof.

Если же мы приводим, а тип не тот - мы получим ClassCastException.

ну да,смысла нет получается...ничего не понимаю

Сидящих за твоим столом ты не спеши назвать Друзьями...

Их проверяют не вином.... А горем... помощью... годами....
 
 
Сообщения:1056
if( a instanceof B)
{
    B b = (B)a;
}


вот так приводить правильно.
 
 
Сообщения:53
windruf:
if( a instanceof B)
{
    B b = (B)a;
}


вот так приводить правильно.

вот именно. а у нас a не instanceof B,потому что B наследуется от A,а не наоборот. :)

Сидящих за твоим столом ты не спеши назвать Друзьями...

Их проверяют не вином.... А горем... помощью... годами....
 
 
Сообщения:10017
Если класс B наследует А и мы создали new B(), то this - возвращает на самом деле объект B. Даже если метод который this вызывает находится в предке А.

Конечно этого предка может еще наследовать и С, и тогда this может быть как А (если его создали через new A()), так и B, и С (если new B(), new C()).
 
 
Сообщения:1056
Fernandel:
windruf:
if( a instanceof B)
{
    B b = (B)a;
}


вот так приводить правильно.

вот именно. а у нас a не instanceof B,потому что B наследуется от A,а не наоборот. :)

наоборот
A a = new B(); //работает без приведения при условии, что B наследует A

// а так в обратную сторону
if( a instanceof B) // сначала удостоверились, что переменная действительно правильного типа
{
    B b = (B)a;  // а потом привели к нужному типу
}


попытки сделать приведение без проверки типа это ловушка: как только в переменной 'a' появится что-нибудь отличное от объекта класса B или его наследников, программа словит исключение.
 
Модераторы:frymock
Сейчас эту тему просматривают:Нет