Руководство по actionscript. часть 1, стр. 119
В большинстве случаев для реализации конкретной объектно-ориентированной архитектуры вместо абстрактных классов могут быть использованы интерфейсы языка ActionScript. О том, что такое интерфейсы, вы прочтете в гл. 9.
Мы рассмотрели понятие наследования. В конце этой главы применим полученные знания к программе по созданию виртуального зоопарка.
Применение наследования в программе по созданию виртуального зоопарка
В нашей программе «Зоопарк» наследование будет добавлено для решения двух различных задач. Во-первых, мы используем его для описания видов пищи, поглощаемой нашими животными, тем самым, заменив предыдущий подход, заключав-
шийся в добавлении определенного количества калорий животному с помощью метода eat ( ). Во-вторых, мы используем наследование, чтобы основной класс нашего приложения VirtualZoo мог отображаться на экране.
Создание видов пищи
До этого момента наша реализация процесса принятия пищи в программе по созданию виртуального зоопарка была чрезмерно упрощена. Чтобы накормить животное, мы просто вызывали метод eat ( ) над желаемым объектом класса VirtualPet и указывали количество калорий, поглощаемое животным. Для реализма нашей имитации добавим в программу зоопарка виды пищи.
Чтобы не усложнять процесс, мы позволим животному принимать только два вида пищи: суши и яблоки. Суши будут представлены новым классом Sushi, а яблоки — классом Apple. Поскольку оба класса — Sushi и Apple — концептуально представляют пищу, они будут иметь почти одинаковую функциональность. Следовательно, в нашем приложении мы реализуем всю функциональность, необходимую обоим классам Sushi и Apple, в одном суперклассе Food. Классы Sushi и Apple расширят класс Food и через наследование получат доступ к его возможностям.
Класс Food описывает четыре простых метода для получения и изменения имени и значения калорий для заданного продукта. Рассмотрим его код:
package zoo { public class Food { private var calories; private var name;
public function Food (initialCalories) { setCalories(initial Calories);
}
public function getCalories ( ) { return calories;
}
public function setCalories (newCalories) { calories = newCalories;
}
public function getName ( ) { return name;
}
public function setName (newName) { name = newName;
}
Класс Apple задает количество калорий, используемое но умолчанию, для каждого объекта Apple и определяет название продукта для всех объектов Apple. Рассмотрим его код:
package zoo { public class Apple extends Food { // Количество калорий, используемое по умолчанию, для объекта // Apple равно 100
private static var DEFAULT_CALORIES = 100:
public function Apple (initialCalories = 0) { // Если для данного конкретного объекта количество калорий не указано // или если было указано отрицательное число… if (initialCalories <= 0) {
// …использовать значение по умолчанию
initialCalories = Applе. DEFAULT_CALORIES;
}
super(i niti alCalori es);
// Определить название продукта для всех объектов Apple setNameCApple»);
}
}
}
Класс Sushi задает количество калорий, используемое по умолчанию, для каждого объекта Sushi и определяет название продукта для всех объектов Sushi. Рассмотрим его код:
package zoo { public class Sushi extends Food { private static var DEFAULT_CALORIES = 500;
public function Sushi (initialCalories = 0) { if (initialCalories <= 0) { initialcalories = sushi.default_calories;
}
super(initialCalories); setName(«Sushi»);
}
}
}
Чтобы объекты класса VirtualPet могли есть яблоки и суши, мы должны модифицировать метод eat ( ) класса VirtualPet. Вот как выглядел метод eat ( ) до настоящего времени:
public function eat (numberOfCalories) { if (currentCalories == 0) { trace(getName( ) + » is dead. You can’t feed it.»); return;
var newCurrentCalories = currentCalories + numberOfCalories; if (newCurrentCalories > VirtualPet. maxCalories) {
currentCalories = Virtual Pet. maxCalories; } else {
currentCalories = newCurrentCalories;
}
trace(getName( ) + » ate some food. It now has » + currentCalories + » calories remaining.»);
}
В новой версии метода eat ( ) мы переименуем параметр numberOfCalories в foodltem, введя тем самым логическое соглашение, что аргументом метода eat ( ) должен быть экземпляр любого класса, унаследованного от класса Food (в гл. 8 будет рассмотрено, как обеспечить выполнение этого соглашения с помощью объявления типа). Внутри метода eat ( ) значение переменной newCurrentCalories будет вычисляться путем сложения значения калорий принимаемого куска пищи (то есть foodltem. getCalories( ))и существующего количества калорий у животного (то есть currentCalories). Наконец, при выводе информации о том, что животное съело пищу, мы воспользуемся методом getName ( ) класса Food, чтобы указать название съеденной пищи. Рассмотрим измененный метод eat ( ):