Частные методы в наследовании

Здесь интересный фрагмент кода:

public class Superclass {

    public static void main (String[] args){
        Superclass obj = new Subclass();
        obj.doSomething(); #prints "from Superclass"
    }

    private void doSomething(){System.out.println("from Superclass");}
}

class Subclass extends Superclass {

    private void doSomething(){System.out.println("from Subclass");}

}

Я знаю, что подклассы не наследуют частных членов своего родителя, но здесь obj удается вызвать метод, к которому у него не будет доступа. Во время компиляции obj имеет тип Superclass, во время выполнения типа Subclass.

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

Итак, вопрос сводится к тому, как obj имеет доступ к частному члену своего родителя?

Ответ 1

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

Ответ 2

Частные методы предназначены только для владельца.

Даже для детей, родственников или друзей владельца.

Ответ 3

Superclass obj = new Subclass();

В этот момент obj есть обе вещи, a Subclass и a Superclass. Тот факт, что вы используете Superclass в объявлении переменной, - это просто вопрос ее литья.

Когда вы выполните: obj.doSomething(), вы сообщаете компилятору вызывать частный метод doSomething() obj. Поскольку вы делаете это из основного статического метода внутри Superclass, компилятор может его вызвать.

Если бы вы использовали основной метод Subclass, а не тот, что был в Superclass, вы не смогли бы получить доступ к этому методу, потому что, как вы сказали, он не унаследовал и не части вашего определения Subclass.

Итак, в основном вы правильно поняли наследование. Проблема была связана с видимостью частных методов.

Ответ 4

Когда вы использовали эту строку:

Superclass obj = new Subclass();

Вы добавили подкласс в объект суперкласса, который использует только методы Суперкласса и те же данные. Если вы вернете его обратно в подкласс, вы можете снова использовать методы подкласса, например:

((Subclass)obj).doSomething(); #prints "from Subclass"

Ответ 5

Это работает, потому что вы выполняете Superclass из метода Superclass. В этом контексте компилятор доступен Superclass.doSomething.

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

Ответ 6

Поскольку ссылочным типом объекта obj является SuperClass, вызов doSomething() пытается получить доступ к приватному методу, определенному в SuperClass (частные методы не могут быть переопределены). Поскольку doSomething() доступен в SuperClass, метод main может вызывать doSomething() без каких-либо ошибок /s.

Надеюсь, это поможет!: -)

Ответ 7

Почему в первую очередь можно вызвать doSomething()?

Почему бы и нет? obj - это экземпляр как Subclass и Superclass, а как doSomething() объявлен в Superclass, а obj используется в нем, поэтому вы имеете доступ к Superclass.doSomething(), вы можете попробовать переименуйте свой метод (, например: doAnotherThing()), и у вас все равно будет доступ к нему.

как obj имеет доступ к частному члену своего родителя?

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

Итак, что?

Нет никакого отношения/наследования между Superclass частными методами и Subclass частными методами, даже если они имеют одинаковое имя и подпись, из Java Language Спецификация, Java SE 8 Edition:

Частный метод и все методы, объявленные сразу в финале класс (§8.1.1.2) ведут себя так, как будто они являются окончательными, поскольку невозможно для их замены.

Ответ 8

Чтобы понять этот вопрос, вы можете связать частный метод с переменной-членом суперкласса и подкласса.

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

Например:

Class A{
 int i = 10;
}

Class B extends A{
  int i = 11;
}

Class C extends A {
   int i = 12;
}

A a1 = new B();
print(a1.i) // Will print 10

A a2 = new B();
print(a2.i) // Will print 10 

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

Ответ 9

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

Поскольку частный метод даже не виден вне класса, мы никогда не сможем вызвать частный метод private класса из производного класса, он вызовет ошибку компиляции:

Исключение в потоке "main" java.lang.Error: Неразрешенная проблема компиляции:   Метод aPrivateMethod() из типа Base не отображается

Мы можем использовать down casting для ссылки родительского класса для вызова частного метода производного класса, к которому можно получить доступ только в этом производном классе.