Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Java. Наследование: правила, синтаксис. Сокрытие имен.




 

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

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

Основные принципы наследования классов:

Подкласс всегда наследует все свойства и методы, определенные в его надклассе.

Подкласс может переопределять наследуемые свойства и методы, а также создавать новые — и это никак не должно отражаться на одноименных свойствах и методах надкласса.

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

Объекты подкласса должны инициализироваться только в момент своего создания.

 

Модификаторы доступаМодификаторы доступа можно рассматривать как с позиции инкапсуляции так и наследования.Если рассматривать с позиции наследования,то модификаторы доступапозволяют путем установки доступа указать члены класса, которые будут наследоваться классом наследником автоматически, а какие нет. Например, переменная или метод, объявленная как public в данном классе будет автоматически перениматься в классе потомке.

 

Модификатор доступа Область доступа
public Без ограничений
private Только из данного класса
protected Из данного класса и его потомков
Без модификатора Для всех классов данного пакета

 

Классы-адаптеры и внутренние классы как альтернатива множественному наследованию.

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

Как известно, в Java запрещено множественное наследование от классов, в отличие от интерфейсов. Что же делать, если пользователь хочет наследовать класс-адаптер и какой-то другой класс одновременно, например, Applet ? Решение этой проблемы состоит в применении внутреннего класса, расширяющего адаптер. Ниже приведен фрагмент кода с внутренним классом:

 

public class MyClass extends Applet

{
...

// Конструктор
MyClass()

{

addMouseListener(new MyAdapter());

}
...

// Внутренний класс, расширяющий адаптер.
class MyAdapter extends MouseAdapter

{
public void mouseClicked(MouseEvent e)

{
...//Код обработки события.
}
}
}

 

Можно еще больше сократить код, если использовать анонимное (без имени) определение внутреннего класса следующим образом.

public class MyClass extends Applet

{
...
// Конструктор
MyClass()
{
addMouseListener(new MouseAdapter()

{
public void mouseClicked(MouseEvent e)

{
...//Код обработки события
}
});
}
...
}

 






















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

 

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

 










Последнее изменение этой страницы: 2018-05-27; просмотров: 190.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...