Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Коллоквиум 2012.doc
Скачиваний:
25
Добавлен:
25.08.2019
Размер:
346.11 Кб
Скачать

5. Иерархические отношения в Java

Представление иерархических отношений. Наследование. Интерфейсы и абстрактные классы.

Для определения подкласса некоторого класса в Java используется ключевое слово extends. Каждый подкласс наследует все переменные и методы своего родителя – суперкласса, т.е. подкласс шире, чем суперкласс. Кроме того, важно, что каждый объект подкласса является и полноправным объектом суперкласса. Определяя подкласс посредством расширения суперкласса, нужно указать отличия между ними. Проектируя классы, следует помещать методы общего назначения в суперкласс, а более спец. методы – в подкласс.

Если методы суперкласса не подходят для подкласса, то нужно переопределить метод. След. учитывать, что подкласс не имеет доступа к приватным полям суперкласса.

Финальные классы - это классы, объявленные с модификатором final. Для таких классов запрещено определять подклассы. Объявление классов как нерасширяемых позволяет компилятору Java выполнять некоторую оптимизацию вызовов его методов.  У любого класса есть суперкласс. Если он не указан явно в конструкции extends, то родителем класса считается класс Object, возглавляющий всю иерархию объектов Java. Конструктор подкласса для вызова конструктора своего суперкласса может использовать конструкцию super(). Ограничения на использование super() таковы:  - конструкцию super() можно использовать только в теле конструктора;  - вызов конструктора суперкласса должен быть самым первым оператором тела конструктора (он должен предшествовать даже объявлениям переменных).  Если в конструкторе подкласса отсутствует явный вызов конструктора суперкласса, то Java вставляет в самое его начало вызов super() неявно. Если в суперклассе отсутствует конструктор без аргументов, то возникает ошибка компиляции. Т.о. при создании объекта любого класса в Java последовательно вызывается цепочка конструкторов, начинающаяся с конструктора головного класса Object. 

Совокупность всех классов, производных от общего суперкласса, наз-ся иерархией наследования. Путь от конкретного класса к его потомкам в иерархии наз-ся цепочкой наследования. Обычно для класса их сущ. несколько. Однако множественное наследование в Java не поддерживается: вместо этого исп-ся механизм интерфейсов.

Сущ. простое правило, позволяющее определить, стоит ли в конкретной ситуации применять наследование или нет. Если между объектами сущ. отношение «является» («is a»), то каждый объект подкласса явл-ся объектом суперкласса. Другой способ – принцип подстановки: объект подкласса можно исп-ть вместо любого объекта суперкласса.

При построении иерархии наследования часто оказывается, что метод, общий для всех подклассов и поэтому определенный в суперклассе, не может быть запрограммирован в этом суперклассе никаким полезным алгоритмом, поскольку в каждом подклассе он разный. Java позволяет определять метод без его реализации, отмечая его как abstract. Вместо тела таких методов указывается ";". Правила для абстрактных методов и содержащих их абстрактных классов: - Любой класс, включающий абстрактный метод, автоматически становится абстрактным классом; - Абстрактный класс должен содержать хотя бы один абстрактный метод. Класс может быть объявлен abstract даже в том случае, когда он не содержит ни одного абстр. метода. Этим гарантируется невозможность создания экземпляров такого класса.  Абстрактный класс не может иметь экземпляров. Подкласс абстрактного класса может иметь экземпляры, если в нем переопределяются все абстрактные методы его суперкласса, и обеспечивается реализация для каждого из них.  Если подкласс абстрактного класса не реализует все унаследованные абстр. методы, он сам становится абстрактным. 

Интерфейс представляет собой класс, в котором все поля — константы (т.е. статические — static  и неизменяемые — final), а все методы абстрактные.

При описании интерфейса вместо ключевого слова class используется ключевое слово interface, после которого указывается имя интерфейса, а затем, в фигурных скобках список полей-констант и методов. Никаких модификаторов перед объявлением полей и методов ставить не надо: все поля автоматически становятся public static final, а методы — public abstract. Методы не могут иметь реализации, т.е. после закрывающей круглой скобки сразу ставится точка с запятой.

Класс может реализовывать интерфейс, т.е. перенимать его поведение. Эта процедура аналогична наследованию, только вместо ключевого слова extends используется ключевое слово implements. Но если после extends  может быть указан только один класс, то после implements  можно перечислить через запятую произвольное количество интерфейсов. Класс может одновременно наследовать от другого класса и реализовывать интерфейсы.

Интерфейсы в Java являются таки же типами данных, как и классы. Если класс реализует какой-либо интерфейс, то экземпляры этого класса могут быть присвоены переменным, имеющим тип реализуемого интерфейса.  Интерфейсы, являясь особым видом классов, могут расширяться подинтерфейсами. При этом подинтерфейс может наследовать сразу несколько суперинтерфейсов.  В Java имеет смысл определять и использовать пустые интерфейсы-метки, не объявляющие ни одного метода. Смысл использования таких интерфейсов - сгруппировать на основе какого-либо свойства несколько классов. Примером интерфейса-метки служит интерфейс Clonable из пакета java.lang, он позволяет идентифицировать класс, для которого существует метод clone() класса Object, позволяющий получить копию объекта. Проверить, реализует ли некоторый класс какой-либо интерфейс (в том числе интерфейс-метку) позволяет оператор instanceof. 

Перегрузка методов экземпляра (не статических методов): Метод m1 класса C перегружает метод m2 класса A с той же сигнатурой, тогда и только тогда, когда: Класс C является наследником класса A либо: - m2 не является private и доступен из C - m1 перегружает m3, который перегружает m2 и отличен от m1 и m2 Если m1 не является abstract, то говорят что он реализует абстрактные методы, которые перегружает. Для доступа к перегруженному методу используется super. Приведение к типу суперкласса, содержащего объявление перегруженного метода, не обеспечивает вызов этого метода (виртуальный полиморфизм) в отличие от обеспечения доступа к сокрытым переменным. static, private, final методы не могут быть перегружены.

Если класс декларирует статический метод, то этот метод скрывает методы с той же сигнатурой объявленные в его суперклассах Для доступа к сокрытому методу можно использовать выражение со словом super, либо квалифицированное имя, либо приведение к типу класса в котором этот метод объявлен. В этом случае сокрытые методы ведут себя также как и сокрытые поля Статический метод не может скрывать метод экземпляра (не являющийся статическим)

Перегружаемые и скрываемые методы должны совпадать не только по сигнатуре но и по возвращаемому значению Перегружающий или перекрывающий метод должен иметь такой же, либо более открытый уровень доступа: public -> public protected -> protected, public package(default) -> package(default), protected, public private методы не наследуются и не перегружаются поэтому могут иметь совпадающую сигнатуру, но разные возвращаемые значения и не совместимые списки throws на разных уровнях абстракции