Наследование Java - переопределение переменных экземпляра - PullRequest
11 голосов
/ 17 марта 2010

Почему переменные экземпляра суперкласса не переопределены в наследовании?

Ответы [ 3 ]

28 голосов
/ 17 марта 2010

Вы можете скрыть поле, но не переопределить оно.

Сокрытие означает, что поле будет иметь различное значение в зависимости от того, к какому классу оно обращено. Поле в подклассе будет «скрывать» поле в суперклассе, но оба существуют.

Это очень плохая практика, чтобы скрыть поле, но работает:

public class HideField {

    public static class A
    {   
        String name = "a";

        public void doIt1() { System.out.println( name ); };
        public void doIt2() { System.out.println( name ); };   
    }

    public static class B extends A
    {
        String name = "b";

        public void doIt2() { System.out.println( name ); };
    }

    public static void main(String[] args)
    {
        A a = new A();
        B b = new B();

        a.doIt1(); // print a
        b.doIt1(); // print a
        a.doIt2(); // print a
        b.doIt2(); // print b <-- B.name hides A.name
    }
}

В зависимости от того, был ли метод переопределен , доступ к полю в A или B осуществляется.

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

25 голосов
/ 17 марта 2010

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

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

1 голос
/ 09 февраля 2018

Потому что:

  • Может нарушить код parent class. Например, рассмотрим следующий код (Как будет выглядеть поведение строки obB.getInt(); в следующем коде, если разрешено переменные экземпляра, переопределяющие ):

    class A
    {
        int aInt;
    
        public int getInt()
        {
            return aInt;
        }
    }
    
    class B extends A
    {
        int aInt;
    
        public int getInt2()
        {
            return aInt;
        }
    
        public static void main(String[] args)
        {
             B obB = new B();
    
             //What would be behavior in following line if, 
             //instance variables overriding is allowed
             obB.getInt(); 
        }
    }
    
  • Это не логично , поскольку child class должно иметь / отражать все виды поведения из parent class.

Итак, вы можете только скрыть унаследованные методы / переменные в child class, но не можете override.

Ниже приводится выдержка из Java-документа из Oracle , указывающая , какую операцию вы можете / ожидать от child class:

Вы можете использовать унаследованные элементы как есть, заменить их, скрыть их или дополнить новыми:

  • Унаследованные поля можно использовать напрямую, как и любые другие поля.
  • Вы можете объявить поле в подклассе с тем же именем, что и поле в суперклассе, тем самым скрывая его (не рекомендуется).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...