Закрытый метод, определенный в `Sub` и` Super`, оба метода могут быть вызваны в Object of Sub, тогда почему закрытый метод сказал, что он не наследуется? - PullRequest
0 голосов
/ 06 мая 2019

Согласно Oracle Tutorials

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

[Вопрос] Для отношения класса как Sub extends Super Понятно, что в документации Oracle говорится, что просто для поддержки факта "могут быть переопределены только унаследованные методы", но это своего рода вводящее в заблуждение утверждение , как будто оно подразумевает => , еслиметод не наследуется, тогда он не представлен как поведение объекта класса Sub, и если это так, то он никоим образом не может быть вызван для объекта класса Sub.Но метод в классе Super может вызывать закрытый метод, определенный в классе Super для объекта подкласса .Пожалуйста, обратитесь к пунктам ниже и к соответствующему коду и предложите, если есть какой-то пробел в моем понимании?

Я всегда понимал наследование, как ниже 3 пункта

  1. Класс Sub наследует все экземплярыметоды и поля (включая приватный).
  2. Если метод приватный в Super, то он не виден в Sub, но это не означает, что объект Sub не имеет поведения,

Код для точек 1 и 2

public class Super{
    private void privateMethod(){
        System.out.println("private method defined in Super");
    }
    public void m(){
        privateMethod();
    }
}

public class Sub extends Super{

} 
public void Other{
    public static void main(String[] args){
        Sub s = new Sub();
        s.m(); 
    }
}

Мы создали объект Sub, m() наследуется Sub иего public означает, что к нему можно получить доступ к коду вне Super.При вызове m() мы можем вызвать privateMethod().Если бы частные методы не были унаследованы, то возникло бы какое-то исключение времени выполнения, а это не так.

Overriding применимо только к видимым методам экземпляра только в классе Sub.Если метод невидим и определен в обоих классах, Sub и Super, тогда объект обладает обеими возможностями, и оба метода могут быть вызваны кодом, который может обращаться к конкретному методу (см. Код ниже)

Код для точки 3

public class Super{
    private void privateMethod(){
        System.out.println("private method defined in Super");
    }
    public void m(){
        privateMethod();
    }
}

public class Sub extends Super{
    private void privateMethod(){
        System.out.println("private method defined in Sub");
    }
    public void m2(){
        privateMethod();
    }
} 
public class Other{
    public static void main(String[] args){
        Sub s = new Sub();
        s.m(); // m() will invoke private method of Super
        s.m2(); // m2() will invoke private method of Sub
    }
}

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

Ответы [ 2 ]

1 голос
/ 06 мая 2019

Я думаю, что ключевое отличие состоит в том, как в спецификации языка Java используется термин «наследовать». (Обратите внимание, что JLS является официальной документацией, а не учебниками по Java.)

JLS 8.2, Члены класса говорит:

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

Но, описывая поведение оператора new, JLS 15.9.4, Оценка во время выполнения выражений создания экземпляров класса говорит (выделено мое):

Новый объект содержит новые экземпляры всех полей, объявленных в указанном типе класса , и всех его суперклассов .

Это означает, что поля суперкласса не наследуются подклассом, но объект instance подкласса все еще содержит эти поля. То же самое относится и к частным методам .

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

Это работает из-за отношения подтипов ("is-a"). Экземпляр подтипа является экземпляром супертипа. Класс не наследует этих членов в себя, но экземпляр класса все еще содержит их.

0 голосов
/ 06 мая 2019

В приведенном вами примере privateMethod из класса Super действительно является частным и не может быть унаследовано Sub.Такой дизайн подразумевает, что мы не хотим, чтобы подклассы могли иметь поведение privateMethod, поэтому нелогично переносить privateMethod в открытом методе, который класс Sub может затем выполнить и иметь "личное поведение"».Таким образом, эта реализация не будет использоваться в реальной жизни.

И поскольку privateMethod не наследуется Sub, реализованная в нем privateMethod является не переопределением, а скорее методом, который происходит симеть одинаковую подпись.Если вы не определили метод в Sub, вы не смогли бы использовать s.m2() (то есть s.privateMethod()).

Но метод в классе Super может вызыватьзакрытый метод, определенный классом Super

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

...