Закрытые члены в наследовании Java

Мне сказали, что для подкласса Java он может наследовать всех членов своего суперкласса. Так это означает, что даже частные члены? Я знаю, что он может наследовать защищенные члены.

Может кто-то объяснить это мне. Я сейчас в полном замешательстве.


person Mandy M    schedule 01.07.2011    source источник


Ответы (5)


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

Из Java Documentation,

Частные участники в суперклассе

Подкласс не наследует частные члены своего родительского класса. Однако, если у суперкласса есть общедоступные или защищенные методы для доступа к его закрытым полям, они также могут использоваться подклассом. Вложенный класс имеет доступ ко всем закрытым членам окружающего его класса — как к полям, так и к методам. Следовательно, открытый или защищенный вложенный класс, унаследованный подклассом, имеет косвенный доступ ко всем закрытым членам суперкласса.

Из JLS,

Члены класса, объявленные закрытыми, не наследуются подклассами этого класса. Только члены класса, которые объявлены как protected или public, наследуются подклассами, объявленными в пакете, отличном от того, в котором объявлен класс.

Полезная ссылка: Наследуют ли подклассы частные поля?

person Saurabh Gokhale    schedule 01.07.2011
comment
Чтобы уточнить, все поля и методы все еще существуют для подклассов, но они доступны только косвенно через незакрытый метод, который может получить к ним доступ (или отражение) - person Peter Lawrey; 09.10.2018
comment
@PeterLawrey, это очень важный момент для всех, кто хочет глубоко понять архитектуру языка. Я предполагаю, что все члены супертипа (ов) (включая частные) размещаются в куче в адресе/области одного и того же экземпляра подкласса (отладчик показывает частные члены суперкласса как часть дочернего класса. ... и насколько мне известно, во время создания экземпляра дочернего класса соответствующие экземпляры суперкласса НЕ создаются отдельно... скорее их члены включаются в экземпляр дочернего класса).. они просто недоступны напрямую. - person Giorgi Tsiklauri; 16.07.2021

Это зависит от вашего точного использования слова наследование. Я объясню на примере.

Предположим, у вас есть два класса: Parent и Child, где Child расширяет Parent. Кроме того, у Parent есть личное целое число с именем value.

Теперь возникает вопрос: наследует ли Child частное value? В Java наследование определено таким образом, что ответ будет "Нет". Однако в общем жаргоне ООП есть небольшая двусмысленность.

Можно сказать, что он не унаследован, потому что нигде Child не может ссылаться явно на value. т.е. любой код, подобный this.value, нельзя использовать внутри Child, а также нельзя использовать obj.value из какого-либо вызывающего кода (очевидно).

Однако в другом смысле можно сказать, что value наследуется. Если вы считаете, что каждый экземпляр Child также является экземпляром Parent, то этот объект должен содержать value, как определено в Parent. Даже если класс Child ничего об этом не знает, частный член с именем value все еще существует в каждом экземпляре Child. Так что в этом смысле можно сказать, что value унаследовано от Child.

Поэтому, не используя слово «наследование», просто помните, что дочерние классы не знают о закрытых членах, определенных в родительских классах. Но также помните, что эти частные члены все еще существуют в экземплярах дочернего класса.

person Ken Wayne VanderLinde    schedule 01.07.2011

Здесь вы останетесь довольны на все 100%. Я проверил это на своем компьютере и то, что я пришел к выводу, я собираюсь опубликовать его здесь. Просто пройдите программу, написанную ниже, посмотрите вывод программы и ПРОЧИТАЙТЕ ЗАКЛЮЧЕНИЕ, приведенное в конце. Чтобы проверить это самостоятельно, скопируйте всю программу и сохраните ее в файле с именем «InheritanceTest.java», затем скомпилируйте ее и, наконец, запустите.

Программа

// Testing if a subclass can access the private members of a superclass

class Class1 {
    private String name;

    public void setName(String name) {
        this.name = name;
        System.out.println("The name has been set successfully.");
    }

    public void showName() {
        System.out.println("The name is: " + name);
    }
}

class Class2 extends Class1 {
    private int age;

    public void setAge(int age) {
        this.age = age;
        System.out.println("The age has been set successfully.");
    }

    public void showAge() {
        System.out.println("The age is: " + age);
    }

    public void displayName() {
        //Accessing the private member of superclass here
        //System.out.println("The name is: " + name); //error, can't compile because access to the private member name of the superclass Class1 is not permitted here.
    }
}

class InheritanceTest {
    public static void main(String[] args) {

        Class1 c1 = new Class1();
        Class2 c2 = new Class2();

        c1.setName("Name_C1");
        c2.setName("Name_C2"); //No error, setName() is a public member of the superclass which indirectly gives access to the private member "name".

        c1.showName();
        c2.showName(); //No error, showName() is a public member of the superclass which indirectly gives access to the private member "name".

        c2.setAge(25);
        c2.showAge();

        //c2.displayName(); //error
    }
}

Выход

The name has been set successfully.
The name has been set successfully.
The name is: Name_C1
The name is: Name_C2
The age has been set successfully.
The age is: 25

Вывод

Да, подкласс может косвенно обращаться к закрытым членам суперкласса. Подкласс не может напрямую обращаться к закрытым членам суперкласса.

Все общедоступные, частные и защищенные члены (т. е. все поля и методы) суперкласса наследуются подклассом, но подкласс может напрямую обращаться только к общедоступным и защищенным членам суперкласса. Если унаследованный член от суперкласса предоставляет доступ к частному члену суперкласса, то подкласс может использовать этот унаследованный член для доступа к частному члену суперкласса.

person Zulfequar Ali    schedule 03.11.2018

ИМО никоим образом не является вопросом определения. Наследование на основе классов подразумевает распространение поведения на потомков. Поскольку такие частные члены ДЕЙСТВИТЕЛЬНО наследуются, я не буду вдаваться в подробности того, как это происходит.

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

Обычно в компьютерных науках «развитие предшествует пониманию», однако давайте не будем строить (или разрушать) нашу концептуализацию ООП, предполагая неправильное «определение», принятое каким-то техническим специалистом, пишущим руководство по хорошо известной ООП-платформе на основе классов.

Извините, что что-то сказал в таком старом посте, но проблема всегда актуальна.

person gkakas    schedule 27.04.2012
comment
Сводится к тому, что означает наследование. В документе, на который ссылается @roadRunner, есть оба варианта: в начале говорится, что подкласс наследует все члены (поля, методы и вложенные классы) от своего суперкласса. затем противоречит себе, говоря, что он не наследует частные члены. Лично я думаю, что они наследуются, потому что здесь они просто не доступны напрямую. Мне любопытно, есть ли реальное определение того, что означает «наследовать» для Java или, возможно, ООП в целом. - person sharakan; 28.04.2012
comment
@sharakan: сегодня у нас есть только де-факто определение. - person gkakas; 31.05.2012
comment
Таким образом, если мы сравним две альтернативы, которые кажутся де-факто дефинициями, то одна из них увидит следующее: предположение о том, что частные члены не наследуются, полностью вводит в заблуждение и опасно для нового разработчика, который думает, что частные члены суперкласса (состояние и элементы поведения) исчезли. Таким образом, можно с уверенностью принять только одно из определений. Таким образом, нет вопроса о другом определении, которое легло в основу моего первоначального сообщения (независимо от определения). Другое определение не делает предположений ;-) - person gkakas; 31.05.2012

Хотя https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 показывает, что частные члены не наследуются. Фактически, он наследуется подклассом. Когда мы используем отладчики для трассировки переменных, они будут показывать закрытые члены под меткой «унаследованные», так что просто попробуйте. есть еще один пост, обсуждающий этот вопрос, и большинство из них думают, что он не унаследован, что вводит в заблуждение многих людей, в том числе и меня поначалу.

person longe    schedule 28.07.2018