Все эти вопросы можно не брать в голову. Вложенные классы в Java используются, как правило, только в самом простом виде, главным образом при обработке событий, возникающих при действиях с мышью и клавиатурой.
В примере с домашними животными мы сделали объект person класса Master — владелец животного — полем класса Pet. Если класс Master больше нигде не используется, то можно определить его прямо внутри класса Pet, сделав класс Master вложенным (inner) классом. Это выглядит следующим образом:
class Pet{
// В этом классе описываем общие свойства всех домашних любимцев. class Master{
// Хозяин животного. string name; // Фамилия, имя.
// Другие сведения...
void getFood(int food, int drink); // Кормление.
// Прочее...
}
int weight; // Вес животного.
int age; // Возраст животного.
Date eatTime[]; // Массив, содержащий время кормления.
int eat(int food, int drink, Date time){ // Процесс кормления.
// Начальные действия.
if (time == eatTime[i]) person.getFood(food, drink);
// Метод потребления пищи...
}
void voice(); // Звуки, издаваемые животным.
// Прочее.
}
Вложение класса удобно тем, что методы внешнего класса могут напрямую обращаться к полям и методам вложенного в него класса. Но ведь того же самого можно было добиться по-другому. Может, следовало расширить класс Master, сделав класс Pet его наследником?
В каких же случаях следует создавать вложенные классы, а когда лучше создать иерархию классов? В теории ООП вопрос о создании вложенных классов решается при рассмотрении отношений "быть частью" и "являться".
Отношения "быть частью" и "являться"
Теперь у нас появились две различные иерархии классов. Одну иерархию образует наследование классов, другую — вложенность классов.
Определив, какие классы будут написаны в вашей программе и сколько их будет, подумайте, как спроектировать взаимодействие классов. Вырастить пышное генеалогическое дерево классов-наследников или расписать "матрешку" вложенных классов?
Теория ООП советует прежде всего выяснить, в каком отношении находятся объекты классов Master и Pet — в отношении "класс Master является экземпляром класса Pet" или в отношении "класс Master является частью класса Pet". Скажем, "собака является животным" или "собака является частью животного"? Другой пример: "мотор является автомобилем" или "мотор является частью автомобиля"? Ясно, что собака — животное и в этой ситуации надо выбрать наследование, но мотор — часть автомобиля и здесь надо выбрать вложение.
Отношение "класс А является экземпляром класса В" по-английски записывается как "a class A is a class B", поэтому в теории ООП называется отношением "is-a". Отношение же "класс А является частью класса В" по-английски "a class A has a class B", и такое отношение называется отношением "has-a".
Отношение "is-a" — это отношение "обобщение-детализация", отношение большей и меньшей абстракции, и ему соответствует наследование классов.
Отношение "has-a" — это отношение "целое-часть" и ему соответствует вложение классов.
Вернемся к нашим животным и их хозяевам и постараемся ответить на вопрос: "класс Master является экземпляром класса Pet" или "класс Master является частью класса Pet"? Ясно, что не верно ни то, ни другое. Классы Master и Pet не связаны ни тем, ни другим образом. Поэтому мы и сделали объект класса Master полем класса Pet.
Заключение
После прочтения этой главы вы получили представление о современной парадигме программирования — объектно-ориентированном программировании и реализации этой парадигмы в языке Java. Если вас заинтересовало ООП, обратитесь к специальной литературе [3—6].
Не беда, если вы не усвоили сразу принципы ООП. Для выработки "объектного" взгляда на программирование нужны время и практика.
Вопросы для самопроверки
1. Какие парадигмы возникали в программировании по мере его развития?
2. Какова современная парадигма программирования?
3. Что такое объектно-ориентированное программирование?
4. Что понимается под объектом в ООП?
5. Каковы основные принципы ООП?
6. Что такое класс в ООП?
7. Какая разница между объектом и экземпляром класса?
8. Что входит в класс Java?
9. Что такое конструктор класса?
10. Какая операция выделяет оперативную память для объекта?
11. Что такое суперкласс и подкласс?
12. Как реализуется полиморфизм в Java?
13. Для чего нужны статические поля и методы класса?
14. Какую роль играют абстрактные методы и классы?
15. Можно ли записать конструктор в абстрактном классе?
16. Почему метод main() должен быть статическим?
17. Почему метод main() должен быть открытым?
ГЛАВА 3
Пакеты, интерфейсы и перечисления