- •Содержание
- •Введение
- •1. Основные понятия языка Java иUml
- •Простое приложение
- •Простой апплет
- •Классы и объекты
- •Базовые типы данных
- •Операторы
- •If (obj instanceof java.Awt.Font) {/*операторы*/}
- •Операторы управления
- •UmLкак язык описания объектно-ориентированных программ
- •2. Библиотека стандартаJava_se Наследование
- •Использование super и this
- •Абстрактные классы и интерфейсы
- •Переопределение методов
- •Перегрузка методов
- •Полимофизм и расширяемость
- •Статические методы и полиморфизм
- •Внутренние (inner) классы
- •Вложенные классы (nested)
- •Анонимные классы
- •Использование библиотек классов Файлы. Потоки ввода/вывода
- •Обработка исключительных ситуаций
- •Коллекции
- •Графические интерфейсы пользователя
- •События и их обработка
- •Элементы управления
- •2. Библиотека стандартаJava_ee
- •ТехнологииJsp
Полимофизм и расширяемость
В следующем примере приведение к базовому типу происходит в выражении:
Stone s1 = new White();
Stone s2 = new Black();
Базовый класс Stoneпредоставляет общий интерфейс для всех наследников. Порожденные классы перекрывают эти определения для обеспечения уникального поведения.
// пример # 7 : полиморфизм : StoneRandom.java
class Stone {
public void add() {/*пустая реализация*/}
} class White extends Stone {
public void add() {
System.out.println("добавлен белый камень");
}
} class Black extends Stone {
public void add() {
System.out.println("добавлен черный камень ");
}
} public class StoneRandom {
public static Stone randStone() {
//if((int)(Math.random() * 2)==0) return new Black();
//else return new White();//как альтернативный вариант
switch((int)(Math.random() * 2)){
case 0: return new Black();
case 1: return new White();
default: return null;
}
}
public static void main(String[] args) {
Stone[] s = new Stone[10];
for(int i = 0; i < s.length; i++)
/* заполнение массива камнями*/
s[i] = randStone();
for(int i = 0; i < s.length; i++)
s[i].add();// вызов полиморфного метода
}
}
}
Главный класс StoneRandomсодержитstaticметодrandStone(), который возвращает ссылку на случайно выбранный объект подкласса классаStoneкаждый раз, когда он вызывается. Приведение к базовому типу производится операторомreturn, который возвращает ссылку наBlackилиWhite. Методmain()содержит массив из ссылокStone,заполненный вызовамиrandStone(). На этом этапе известно, что имеется некоторое множество ссылок на объекты базового типа и ничего больше (не больше, чем знает компилятор).Kогда происходит перемещение по этому массиву, методadd()вызывается для каждого случайным образом выбранного объекта.
Если понадобится в дальнейшем добавить систему, например класс Green, то это потребует только переопределения соответствующих методов и добавления одной строки в код методаrandStone(), что делает систему легко расширяемой.
Статические методы и полиморфизм
К статическим методам принципы полиморфизма неприменимы. При использовании для доступа к статическому члену ссылки, компилятор, при выборе метода или поля, учитывает тип ссылки, а не тип объекта, ей присвоенного.
/* пример # 8 : поведение статического метода : StaticDemo.java */
class StaticA {
public static void show(){
System.out.println("метод show() из StaticA");
}
}
class StaticB extends StaticA {}
class StaticC extends StaticB {
public static void show(){
System.out.println("метод show() из StaticC");
}
}
public class StaticDemo {
public static void main(String[] args) {
StaticA s1 = new StaticC();
StaticB s2 = new StaticC();
StaticC s3 = new StaticC();
s1.show();
s2.show();
s3.show();
}
}
В результате выполнения данного кода будет выведено
метод show() из StaticA
метод show() из StaticA
метод show() из StaticC
При таком способе инициализации объектов s1иs2, методshow()будет вызван из суперклассовStaticA и StaticB соответственно.Полиморфизм наблюдается только в смысле наследования методов. Для объектаs3будет вызван собственный методshow(), что следует из способа объявления объекта. Если же спецификаторstaticубрать из объявления методов, то вызовы методов будут осуществляться в соответствии с принципами полиморфизма.
В Javaможно определить (вложить) один класс внутри определения другого класса, что позволяет группировать классы, логически связанные друг с другом, и динамично управлять доступом к ним. С одной стороны, обоснованное использование в коде внутренних классов делает его более эффектным и понятным. С другой стороны, применение внутренних классов есть один из способов сокрытия кода, так как внутренний класс может быть абсолютно недоступен и не виден вне класса-владельца. Внутренние классы также используются в качестве блоков прослушивания событий (глава 12).
Вложенные классы могут быть статическими, объявляемыми с модификатором static, и нестатическими. Статические классы могут обращаться к членам включающего класса не напрямую, а только через его объект. Нестатические внутренние классы имеют доступ ко всем переменным и методам своего класса-владельца.