Я не понимаю эту функциональность наследования - PullRequest
0 голосов
/ 06 января 2012

Рассмотрим следующий недопустимый код: -

class WrongCode{
    int i;
    static int i;
}

Здесь компилятор говорит, что у нас есть дубликаты полей в одном классе.

Теперь рассмотрим следующие классы в одном файле.

class Parent{
    int i = 10;
}

class Child extends Parent{
    static int i = 100;
}

public class Main{
    public static void main(String ... aaa){
        Parent ob = new Child();
        System.out.println(ob.i);   // This prints Parent's i
    }
}

Так как фактический объект - Child, не должен ли ob обращаться к Child's i?И если он ссылается на «i» Родителя, то в некотором смысле он также имеет «i» Родителя в своем собственном классе вместе со своим собственным статическим «i», которое НЕ РАЗРЕШЕНО.

Дочерняя статика i затмевает Parent i.И Parent's i не является статичным, так как же тогда к нему напрямую обращаться с помощью instance, а не className?

Ответы [ 6 ]

2 голосов
/ 06 января 2012

У вас есть поле экземпляра i в Parent классе, и оно остается полем экземпляра в Child классе.

System.out.println(ob.i);  // must be 10

Посмотрите - Oracle Java Tutorial - Скрытие полей

1 голос
/ 06 января 2012

Здесь важно понимать, что System.out.println(ob.i); не может печатать Child i: он знает только, что ob имеет объявленный тип Parent, а не то, что он был создан с помощьюфактический Child.Таким образом, если бы Parent не имело никакого i, произошла бы ошибка компиляции.Если у parent есть i, это печатается.

Я видел, что в SO упоминалось, что доступ к переменным класса через экземпляры (то есть ob.i эквивалентен Parent.i) должен рассматриваться как серьезный проектнедостаток Java.Я согласен, что это иногда может сбивать с толку.В любом случае, у вашего родителя и ребенка также может быть нестатический i, и он не обязательно должен быть одинаковым.Приведенный выше аргумент должен быть применим к рассуждению, какое из них будет напечатано в какой ситуации.

0 голосов
/ 06 января 2012

На самом деле его полиморфизм и ob имеют доступ только к полям родительского класса и поведению, если таковые имеются ...

0 голосов
/ 06 января 2012

При доступе к полям члена класса (переменным экземпляра), например, ob.i.вы получите результаты из класса, который известен во время компиляции, а не из того, что известен во время выполнения.Вот почему у вас есть значение 10, которое является родительским значением.

Для вызовов методов они отправляются во время выполнения объекту фактического класса контрольные точки.

Что касается затенения здесь, это то, что Javaспецификация lang говорит:

Если класс объявляет поле с определенным именем, то объявление этого поля считается скрывающим любые и все доступные объявления полей с одинаковым именем в суперклассах и суперинтерфейсах класса.

Доступ к скрытому полю можно получить с помощью квалифицированного имени (если оно статическое)

спецификация языка

Вы можете ссылаться на «Объявления полей».Раздел.

0 голосов
/ 06 января 2012

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

0 голосов
/ 06 января 2012

В ob дочерний элемент static int i никогда не виден, поскольку ob имеет тип Parent, независимо от того, как он был создан (базовый или производный класс).значение как 10 , что Parent с i значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...