воскресенье, 23 октября 2022 г.

Наследование в Java

   «родительское/дочернее»

    Наследование (inheritance) - свойство системы, позволяющее описать (создать) новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью.
    Класс, от которого производится наследование, называется базовым, родительским или суперклассом, а новый класс - потомком, наследником, дочерним или производным классом. 
    Используется для быстрой и безопасной организации родственных понятий: чтобы было достаточно на каждом иерархическом шаге учитывать только изменения, не дублируя всё остальное, учтённое на предыдущих шагах.

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

 

    Для обозначения наследования в Java служит слово extends.

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

   Чем дальше вверх по иерархии наследования, тем более универсальными и абстрактными становятся классы. Такие классы становятся основой для других классов. И, как правило, запрещается создавать их экземпляры.

 

В Java есть два вида наследования:

  • наследование классов: каждый наследник может иметь только одного родителя;
  • наследование интерфейсов: интерфейс может иметь сколько угодно родителей.

Порядок инициализации объектов при наследовании

  • память, выделенная под новый объект, заполняется двоичными нулями;

  • в начале идет подъем до корня иерархии, а потом сверху вниз вызываются конструкторы один за другим вплоть до класса, конструируемого объекта;

  • инициализируются поля класса в порядке их записи;

  • вызывается тело конструктора нужного объекта.

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

 

Ограничения

  • при наследовании доступ из методов класса-потомка к приватным полям родительского класса напрямую запрещен. Кроме того, данные поля не наследуются. Но благодаря специальным публичным методам, которые называются get/геттеры и set/сеттеры можно совершенно свободно обращаться к данным полям родительского класса из класса-потомка;

  • приватные методы, как и приватные поля также не наследуются. Это значит, что создание метода в классе-потомке с именем, аналогичным имени метода класса-предка — создаст совершенно новый метод и компилятор не предупредит вас об этом. Во избежание таких коллизий при наследовании методов желательно использовать аннотацию @Override. Благодаря данной аннотации компилятор сможет проконтролировать ваш код и выдать предупреждение, если переопределяемый метод не будет найден в родительском классе.

     

Достоинства

  • способствует уменьшению повторяемости кода, т.е. имеет место быть его переиспользование (англ. code reuse);

  • ускоряет разработку. тк наследование позволяет взять готовый класс, "клонировать" его в новый класс-потомок, т.е. получить весь функционал класса-предка, а затем расширить его, добавив новые методы и поля;

Недостатки

  • большое значение имеет правильное построение иерархии классов. Т.к на поздних этапах разработки, когда иерархия классов построена и на её основе разработано большое количество кода, оказывается трудно или даже невозможно внести какие-либо изменения в код базовых классов иерархии;

  • при внесении изменений в базовые классы — классы наследники об этом могут ничего не знать;

  • данный механизм требует, чтобы точный тип объекта был известен уже на стадии компиляции, что делает код, зависящим от реализации;

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

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

 

Когда нужно применять наследование

    Для того что бы определить стоит ли применять наследование нужно для предка и предполагаемого производного класса попробовать установить отношение "является" ("is a").

    Отношение "является" служит признаком наследования.


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

    При наследовании в классе-потомке должна добавляться функциональность, отличающаяся от существующей в классе-предке. Если в наследнике часть функциональности убирается, то это является поводом задуматься о необходимости в данной ситуации наследования.

Комментариев нет:

Отправить комментарий

Наследование в Java

   «родительское/дочернее»     Наследование (inheritance) - свойство системы, позволяющее описать (создать) новый класс на основе уже су...