Мне сказали, что для подкласса Java он может наследовать всех членов своего суперкласса. Так это означает, что даже частные члены? Я знаю, что он может наследовать защищенные члены.
Может кто-то объяснить это мне. Я сейчас в полном замешательстве.
Мне сказали, что для подкласса Java он может наследовать всех членов своего суперкласса. Так это означает, что даже частные члены? Я знаю, что он может наследовать защищенные члены.
Может кто-то объяснить это мне. Я сейчас в полном замешательстве.
Нет, закрытый член не наследуется, потому что область действия закрытого члена ограничена только классом, в котором он определен. Наследуются только открытый и защищенный члены.
Частные участники в суперклассе
Подкласс не наследует частные члены своего родительского класса. Однако, если у суперкласса есть общедоступные или защищенные методы для доступа к его закрытым полям, они также могут использоваться подклассом. Вложенный класс имеет доступ ко всем закрытым членам окружающего его класса — как к полям, так и к методам. Следовательно, открытый или защищенный вложенный класс, унаследованный подклассом, имеет косвенный доступ ко всем закрытым членам суперкласса.
Из JLS
,
Члены класса, объявленные закрытыми, не наследуются подклассами этого класса. Только члены класса, которые объявлены как protected или public, наследуются подклассами, объявленными в пакете, отличном от того, в котором объявлен класс.
Полезная ссылка: Наследуют ли подклассы частные поля?
Это зависит от вашего точного использования слова наследование. Я объясню на примере.
Предположим, у вас есть два класса: 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
.
Поэтому, не используя слово «наследование», просто помните, что дочерние классы не знают о закрытых членах, определенных в родительских классах. Но также помните, что эти частные члены все еще существуют в экземплярах дочернего класса.
Здесь вы останетесь довольны на все 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
Да, подкласс может косвенно обращаться к закрытым членам суперкласса. Подкласс не может напрямую обращаться к закрытым членам суперкласса.
Все общедоступные, частные и защищенные члены (т. е. все поля и методы) суперкласса наследуются подклассом, но подкласс может напрямую обращаться только к общедоступным и защищенным членам суперкласса. Если унаследованный член от суперкласса предоставляет доступ к частному члену суперкласса, то подкласс может использовать этот унаследованный член для доступа к частному члену суперкласса.
ИМО никоим образом не является вопросом определения. Наследование на основе классов подразумевает распространение поведения на потомков. Поскольку такие частные члены ДЕЙСТВИТЕЛЬНО наследуются, я не буду вдаваться в подробности того, как это происходит.
На самом деле я нахожу ответ «не унаследованный» опасным для новых разработчиков, и они не сразу понимают, что частные члены скрыты под кожей вашего класса и они (могут) иметь серьезное влияние на его поведение, размер объекты и т. д.
Обычно в компьютерных науках «развитие предшествует пониманию», однако давайте не будем строить (или разрушать) нашу концептуализацию ООП, предполагая неправильное «определение», принятое каким-то техническим специалистом, пишущим руководство по хорошо известной ООП-платформе на основе классов.
Извините, что что-то сказал в таком старом посте, но проблема всегда актуальна.
Хотя https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 показывает, что частные члены не наследуются. Фактически, он наследуется подклассом. Когда мы используем отладчики для трассировки переменных, они будут показывать закрытые члены под меткой «унаследованные», так что просто попробуйте. есть еще один пост, обсуждающий этот вопрос, и большинство из них думают, что он не унаследован, что вводит в заблуждение многих людей, в том числе и меня поначалу.