- •Наследование
- •Цели занятия
- •Понятие наследования
- •Понятие наследования
- •Понятие наследования
- •Расширенный класс. Конструкторы
- •Расширенный класс. Конструкторы
- •Расширенный класс. Конструкторы
- •Порядок выполнения
- •Порядок выполнения
- •Порядок выполнения
- •Порядок выполнения
- •Порядок выполнения
- •Наследование и переопределение
- •Наследование и переопределение
- •Наследование и переопределение
- •Наследование и переопределение
- •Сокрытие полей. Доступ к
- •Сокрытие полей. Доступ к
- •Сокрытие полей. Доступ к
- •Возможность доступа и
- •Сокрытие статических членов
- •Служебное слово super
- •Служебное слово super
- •Служебное слово super
- •Совместимость
- •Совместимость
- •Совместимость
- •Явное преобразование типов
- •Явное преобразование типов
- •Проверка типа
- •Проверка типа
- •Методы и классы final
- •Методы и классы final
- •Методы и классы final
- •Методы и классы final
- •Методы и классы final
- •Методы и классы abstract
- •Методы и классы abstract
- •Методы и классы abstract
- •Класс Object
- •Методы класса Object
- •Методы класса Object
- •Методы класса Object
- •Методы класса Object
- •hashCode() и equals()
- •Клонирование объектов
- •Клонирование объектов
- •Клонирование объектов
- •Литература
Явное преобразование типов
31• Оператор преобразования типов позволяет сообщить компилятору, что конкретное выражение следует трактовать таким образом, будто оно относится к тому типу, который явно указан
•Оператор может быть применён в любых ситуациях, но его обычное употребление связано всё-таки с преобразованиями, предусматривающими сужение типа
That sref = (That) this;
More mref = (More) sref;
•Преобразование с расширением типа нередко обозначают терминами преобразование вверх или безопасное преобразование, поскольку тип, расположенный на низкой ступени иерархии, приводится к классу более высокого уровня, а подобная операция заведомо допустима
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Явное преобразование типов
32 • Преобразование с сужением типа соответственно называют преобразованием вниз – воздействию подвергается объект базового типа, который должен быть интерпретирован как объект производного типа
•Преобразование вниз – это ещё и небезопасное преобразование, поскольку его результат в общем случае может быть неверен
•Когда компилятор, анализируя исходный текст программы, встречает выражение явного преобразования типов, он всегда проверяет корректность операции
•Если выясняется, что операция некорректна ещё на этапе компиляции, выдаётся соответствующее сообщение об ошибке
•Если же компилятор не в состоянии сразу подтвердить возможность преобразования или опровергнуть её, он добавляет в код дополнительные инструкции, призванные проверить код во время его выполнения
•Когда подобный контроль даёт отрицательный результат, генерируется исключение типа ClassCastException
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Проверка типа
33• Часто возникает задача определения принадлежности объекта тому или иному типу, и решить её позволяет оператор instanceof,
возвращающий в результате вычисления значение true, если выражение левой части совместимо с типом, название которого указано в правой части, и false – в противном случае
•Следует иметь в виду, что null нельзя причислить к какому бы то ни было типу, и поэтому результат применения instanceof по отношению к null всегда равен false
•Используя instanceof, мы можем загодя убедиться в правомерности преобразования с сужением типа, которое хотим выполнить, и избежать
возникновения исключительных ситуаций
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Проверка типа
34 Пример 4
if (sref instanceof More) mref = (More)sref;
•Заметим, что мы всё ещё обязаны применять оператор преобразования типов, чтобы сообщить компилятору о наших истинных намерениях
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Методы и классы final
35• Обозначая метод класса модификатором final, мы имеем в виду, что ни один производный класс не в
состоянии переопределить этот метод, изменив его внутреннюю реализацию
• Класс в целом может быть помечен как final: final class NoExtending {
//…
}
•Класс, помеченный как final, не поддаётся наследованию и все его методы косвенным образом приобретают свойство final
•Применение признака final в объявлениях классов и методов способно повысить уровень безопасности
кода
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Методы и классы final
36• Во многих случаях для достижения достаточного уровня безопасности кода вовсе нет необходимости обозначать весь класс как final – вполне возможно сохранить способность класса к расширению, пометив
модификатором final только его «критические» структурные элементы
•В этом случае вы оставите в неприкосновенности основные функции класса и одновременно разрешите его наследование с добавлением новых членов, но без переопределения «старых»
•Разумеется, поля, к которым обращается код методов final, должны быть в свою очередь помечены как final или private, так как в противном случае любой производный класс получит возможность изменить их содержимое, воздействуя на поведение
соответствующих методов
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Методы и классы final
37• Ещё один эффект применения модификатора final связан с упрощением задачи оптимизации кода,
решаемой компилятором
•Когда вызывается метод, не помеченный как final, исполняющая система определяет фактический класс объекта, связывает вызов с наиболее подходящим кодом из группы перегруженных методов и передаёт управление этому коду
•Но если метод, например, getName(), обозначен как final, операция обращения к нему упрощается
•В самом простом случае, подобном тому, который касается getName(), компилятор может заменить вызов метода кодом его тела
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Методы и классы final
38 • Такой механизм носит название встраивания кода
•При этом два следующих выражения выполняются совершенно одинаково:
System.out.println ("id = " + rose.name);
System.out.println ("id = " + rose.getName());
•Та же схема оптимизации может быть применена компилятором и по отношению к методам private и static, так как и они не допускают переопределения
•Использование модификатора final в объявлениях классов способствует также повышению эффективности некоторых операций проверки типов
•В этом случае многие подобные операции могут быть выполнены уже на стадии компиляции и поэтому потенциальные ошибки выявляются гораздо раньше
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Методы и классы final
39• Если компилятор встречает в исходном тексте ссылку на класс final, он может быть «уверен»,
что соответствующий объект относится именно к тому типу, который указан
•Компилятор в состоянии сразу определить место, занимаемое классом в общей иерархии классов, и проверить, верно тот используется или нет
•Если модификатор final не применяется, соответствующие проверки осуществляются только на стадии выполнения программы
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Методы и классы abstract
40• Вы можете объявить абстрактный класс, представив только часть его реализации и заранее предусмотрев возможность переопределения всех
или некоторых методов в производных классах
•До сих пор мы имели дело с конкретными классами, в которых каждый метод был объявлен полностью
•Абстрактные классы находят широкое применение
в тех случаях, когда, например, некоторые признаки поведения класса приемлемы для всех его объектов, но при этом существуют и такие функциональные особенности, которые целесообразно реализовать только в определённых производных классах, а не в базовом классе непосредственно
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |