Наследование через понижающее и повышающее преобразования типов



 

Наследования классов предусматривает возможности преобразования типов между суперклассом и подклассом. Различаются два вида преобразований типов — 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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!