Читайте также:
|
|
public static void main(String[] args){
Pet[] singer = new Pet[3];
singer[0] = new Dog();
singer[1] = new Cat();
singer[2] = new Cow();
for (int i = 0; i < singer.length; i++)
singer[i].voice();
}
}
На рис. 2.1 показан вывод этой программы. Животные поют своими голосами!
Все дело здесь в определении поля singer[]. Хотя массив ссылок singer [] имеет тип Pet, каждый его элемент ссылается на объект своего типа Dog, Cat, cow. При выполнении программы вызывается метод конкретного объекта, а не метод класса, которым определялось имя ссылки. Так в Java реализуется полиморфизм.
Знатокам C++
В языке Java все методы являются виртуальными функциями.
Внимательный читатель заметил в описании класса Pet новое слово abstract. Класс Pet и метод voice() являются абстрактными.
Рис. 2.1. Результат выполнения программы Chorus
Абстрактные методы и классы
При описании класса Pet мы не можем задать в методе voice () никакой полезный алгоритм, поскольку у всех животных совершенно разные голоса.
В таких случаях мы записываем только заголовок метода и ставим после закрывающей список параметров скобки точку с запятой. Этот метод будет абстрактным (abstract), что необходимо указать компилятору модификатором abstract.
Если класс содержит хоть один абстрактный метод, то создать его экземпляры, а тем более использовать их, не удастся. Такой класс становится абстрактным, что обязательно надо указать модификатором abstract.
Как же использовать абстрактные классы? Только порождая от них подклассы, в которых переопределены абстрактные методы.
Зачем же нужны абстрактные классы? Не лучше ли сразу написать нужные классы с полностью определенными методами, а не наследовать их от абстрактного класса? Для ответа снова обратимся к листингу 2.2.
Хотя элементы массива singer [] ссылаются на подклассы Dog, Cat, Cow, но все-таки это переменные типа Pet и ссылаться они могут только на поля и методы, описанные в суперклассе Pet. Дополнительные поля подкласса для них недоступны. Попробуйте обратиться, например, к полю k класса Dog, написав singer [0].k. Компилятор "скажет", что он не может реализовать такую ссылку. Поэтому метод, который реализуется в нескольких подклассах, приходится выносить в суперкласс, а если там его нельзя реализовать, то объявить абстрактным. Таким образом, абстрактные классы группируются на вершине иерархии классов.
Кстати, можно задать пустую реализацию метода, просто поставив пару фигурных скобок, ничего не написав между ними, например:
void voice(){}
Получится полноценный метод. Но это искусственное решение, запутывающее структуру класса.
Дата добавления: 2015-09-11; просмотров: 72 | Поможем написать вашу работу | Нарушение авторских прав |