Наследование через понижающее и повышающее преобразования типов
Наследования классов предусматривает возможности преобразования типов между суперклассом и подклассом. Различаются два вида преобразований типов — upcasting и downcasting. Повышающее преобразование (upcasting) — это преобразование от типа порожденного класса (от подкласса) к базовому (суперклассу). Такое преобразование допустимо всегда. На него нет никаких ограничений и для его проведения не требуется применять никаких дополнительных синтаксических конструкций. Это связано с тем, что объект подкласса всегда в себе содержит как свою часть объект суперкласса.
Понижающее преобразование (downcasting) — это преобразование от суперкласса к подклассу. Такое преобразование имеет ряд ограничений. Во-первых, оно может задаваться только явно при помощи операции преобразования типов, например,
B b1 = (B) a;
Во вторых, при преобразовании должен использоваться соответствующий тип. Если это не так, то возникает исключение ClassCastException в процессе выполнения программы.
При понижающем преобразовании часто применяется операция instanceof. Эта операция проверяет, имеет ли ее левый операнд класс, заданный правым операндом. Например,
if ( a instanceof B ) b1 = (B)a;
Пример, сочетающий в себе преобразования типов и instanceof:
Рассмотрим иерархию классов Issue — печатное издание, Book — книга, Newspaper - газета, Journal — журнал, где Book, Newspaper и Journal являются наследниками класса Issue.
public class Issue
{
String name;
|
|
public Issue(String name)
{
this.name = name;
}
public void printName(PrintStream out)
{
out.println("Наименование:");
out.println(name);
}
. . .
}
public class Book extends Issue
{
String authors;
public Book(String name, String authors)
{
super(name);
this.authors = authors;
}
public void printAuthors(PrintStream out)
{
out.println("Авторы:");
out.println(authors);
}
. . .
}
А где-то в программе присутствует такой фрагмент:
Issue[] catalog = new Issue[]
{
new Journal("Play Boy"),
new Newspaper("Спид Инфо"),
new Book("Война и мир", "Л.Толстой")
};
. . .
for(int i = 0; i < catalog.length; i++)
{
if ( catalog[i] instanceof Book )
((Book) catalog[i]).printAuthors(System.out);
catalog[i].printName(System.out);
}
Порождается каталог (массив печатных изданий), причем каждое из печатных изданий каталога может быть как книгой, так и газетой или журналом. При построении массива выполняется приведение к базовому типу (upcasting). Далее в цикле мы печатаем информацию из каталога. Причем, для книг кроме наименования печатается еще и список авторов. Для этого с использованием операции instanceof проверяется тип печатного издания, а при самой печати списка авторов элемент каталога преобразуется к типу Book. Если этого не сделать, транслятор выдаст ошибку, т.к. метод printAuthors(...) есть только в классе Book, но не в классе Issue.
Запрет наследования или переопределения с помощью ключевого слова final
|
|
Если нужно запретить переопределение (overriding) метода во всех порожденных классах, то этот метод можно описать как final. Кроме того, ключевое слово final может применяться к классам. Это означает, что данный класс не может быть унаследован другим классом.
Множественное наследование интерфейсов
Интерфейсы допускают множественное наследование. Один класс при этом может удовлетворять нескольким интерфейсам сразу. В этом состоит серьезное отличие интерфейсов от обычных классов и от абстрактных классов. Интерфейсы не порождают проблем с множественным наследованием, поскольку они не содержат полей.
После этого может следовать ключевое слово extends и список интерфейсов, от которых будет наследоваться объявляемый интерфейс. Родительских типов может быть много, главное, чтобы не было повторений, и чтобы отношение наследования не образовывало циклической зависимости.
Наследование интерфейсов действительно очень гибкое. Так, если есть два интерфейса A и B, причем B наследуется от A, то новый интерфейс C может наследоваться от них обоих. Указание наследования от A является избыточным, все элементы этого интерфейса и так будут получены по наследству через интерфейс B.
|
|
public interface Drawble extends Colorable, Resizable
{
}
Класс наследует от прямых суперклассов и прямых суперинтерфейсов все методы (abstract или нет) этих суперклассов и суперинтерфейсов, которые доступны для кода класса и которые не перегружены и не скрыты в объявлении данного класса.
Если объявление метода перегружает или скрывает объявление другого метода, тогда происходит ошибка времени компиляции, если они имеют различные типы возвращения или если один имеет тип возвращения, а другой не возвращает никаких данных (т.е. в его объявлении содержится слово "void"). Более того, объявление метода не должно содержать предложение throws, которое противоречит с этим методом, и которое его замещает или скрывает; иначе происходит ошибка времени компиляции. В этом аспекте замещение методов отличается от сокрытия полей для него допустимо для поля скрыть поле другого типа.
Модификатор доступа замещенного или скрытого метода должен обеспечивать максимальный доступ к замещенным или скрытым методам, иначе происходит ошибка времени компиляции. Более подробно:
Если замещаемый или скрываемый метод объявлен как public, тогда замещение или сокрытие метода должно быть public; иначе происходит ошибка времени компиляции.
|
|
Если замещемый или скрываемый метод объявлен как protected, тогда замещение или сокрытие метода должно быть protected или public; иначе происходит ошибка времени компиляции.
Если замещенный или скрытый метод имеет доступ по умолчанию (пакета), тогда замещение или сокрытие метода не должно быть private; иначе присходит ошибка времени компиляции.
Заметьте, что private-метод никогда не доступен для подклассов и поэтому не может быть скрытым или замещенным в техническом смысле этого понятия. Такой способ, что подкласс может объявлять метод с той же самой сигнатурой как private-метод в одном из суперклассов, и не существует ограничения, чтобы тип возвращения или метод throws такого метода имел какую-либо взаимосвязь с private-методами в суперклассе.
Дата добавления: 2018-05-13; просмотров: 558; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!