
- •Основы классов
- •Общая форма класса
- •Простой класс
- •Объявление объектов
- •Операция new
- •Представление методов
- •Добавление метода к классу Box
- •Возврат значений
- •Добавление метода с параметрами
- •Конструкторы
- •Параметризованные конструкторы
- •Ключевое слово this
- •Скрытие переменной экземпляра
- •Сборка "мусора"
- •Метод finalize()
- •Класс Stack
- •Перегрузка конструкторов
- •Использование объектов в качестве параметров
- •Передача аргументов
- •Возврат объектов
- •Рекурсия
- •Управление доступом
- •Статические элементы
- •Спецификатор final
- •Ревизия массивов
- •Вложенные и внутренние классы
- •Класс String
- •Использование аргументов командной строки
- •Наследование
- •Основы наследования
- •11 Тело класса }
- •Доступ к элементам и наследование
- •Практический пример
- •Переменная суперкласса может ссылаться на объект подкласса
- •Использование ключевого слова super
- •Вызов конструктора суперкласса с помощью первой формы super
- •Создание многоуровневой иерархии
- •II построить клон объекта
- •Когда вызываются конструкторы
- •Переопределение методов
- •Динамическая диспетчеризация методов
- •Зачем нужны переопределенные методы?
- •Применение переопределения методов
- •Использование абстрактных классов
- •Void meth() { // ошибка! Нельзя переопределять.
- •Класс Object
Перегрузка конструкторов
В дополнение к перегрузке обычных методов можно также перезагружать методы конструкторов. Фактически, для наиболее реальных классов, которые вы создаете, перезагруженные конструкторы будут нормой, а не исключением. Для объяснения этого утверждения вернемся к классу Box, разработанному в предыдущей главе. Самая последняя версия Box выглядит так:
class Box {
double width;
double height;
double depth;
// Это конструктор класса Box.
Box(double w, double h, double d) {
width = w;
height = h;
depth = d; }
// вычислить и возвратить объем
double volume() {
return width * height * depth;
}
}
Здесь конструктор Box() имеет три параметра. Это означает, что все объявления Box-объектов должны переслать в конструктор Box() три аргумента. Например, следующий оператор недопустим:
Box ob = new Box() ;
Так как Box() требует трех параметров, то его вызов без них – это ошибка. Это поднимает несколько важных вопросов. Что, если вы просто хотели построить трехмерный блок и не заботились (или не знали), каковы были его начальные размеры? Или, что, если вы хотите инициализировать куб, определяя только одно значение, которое использовалось бы для всех трех размеров? В предложенной выше форме записи класса box эти возможности вам недоступны.
К счастью, решается проблема совсем просто: перегрузите конструктор box так, чтобы он обрабатывал только что описанные ситуации. Ниже показана программа, содержащая улучшенную версию класса box, который именно это и делает:
/* Класс Box: три конструктора для разных способов
инициализации размеров блока. '*/
class Box {
double width;
double height;
double depth;
// конструктор для инициализации всех размеров
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// конструктор для инициализации без указания размеров
Box() {
width = -1; // использовать -I для указания
height = -1; // не инициализированного
depth = -1; // блока
}
// конструктор для создания куба
Box(double len) {
width = height = depth = len;
}
// вычислить и возвратить объем
double volume() {
return width * height * depth;
}
}
class OverloadCons {
public static void main(String args[]) {
// создать блоки, используя различные конструкторы
Box myboxl = new Box(10, 20, 15);
Box mybox2 = new Box();
Box mycube = new Box(7);
double vol;
// получить объем первого блока
vol = myboxl.volume ();
System.out.println("Объем myboxl равен " + vol);
// получить объем второго блока
vol = mybox2.volume();
System.out.println("Объем mybox2 равен " + vol);
// получить объем куба
vol = mycube.volume();
System.out.println("Объем mycube равен " + vol');
}
}
Вывод, выполненный этой программой:
Объем myboxl равен 3000.0
Объем mybox2 равен -1.0
Объем mycube равен 343.0
Как вы видите, подходящий перегруженный конструктор вызывается, основываясь на параметрах, указанных при выполнении операции new.
Использование объектов в качестве параметров
До сих пор мы использовали в качестве параметров методов только простые типы. Однако существует практика передачи методам объектов. Например, рассмотрим следующую простую программу:
// Объекты можно передавать методам в качестве параметров.
class Test { int a, b;
Test(int i, int j) {
a = i;
Ь = j;
}
// возвратить true, если о равно вызывающему объекту
boolean equals(Test о) {
if(о.а == а && o.b == b)
return true;
else
return false;
}
}
class PassOb {
public static void main (String args[]) {
Test obi = new Test(100, 22);
Test ob2 = new Test(100, 22);
Test ob3 = new Test(-l, -1);
System, out.println("obi == ob2: " + obi.equals(ob2));
System, out.println("obi == оЬЗ: " + obi.equals(оЬЗ));
}
}
Эта программа генерирует следующий вывод:
оЫ == оЬ2 : true
obi == оЬЗ: false
Не трудно видеть, что метод equals о внутри класса Test сравнивает два объекта на равенство и возвращает результат. То есть, он сравнивает вызывающий объект с тем, который передан методу. Если они содержат те же значения, то метод возвращает true. Иначе, он возвращает false. Обратите внимание, что параметр о в методе equals о указывает Test в качестве своего типа. Хотя Test – это тип класса, созданный программой, он используется точно таким же способом, как и встроенные типы Java.
Чаще всего в качестве параметров объекта используются конструкторы. Возможно, вы захотите построить новый объект так, чтобы он был первоначально таким же, как некоторый существующий. Чтобы сделать это, вы должны определить конструктор, который имеет объект своего класса в качестве параметра. Например, следующая версия Box позволяет одному объекту инициализировать другой:
// Здесь Box позволяет одному объекту инициализировать другой.
class Box {
double width;
double height;
double depth;
// построить клон объекта
Box(Box ob) { // переслать объект конструктору
width = ob.width;
height = ob.height;
depth = ob.depth;
}
// конструктор для всех размеров блока
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// конструктор блока без размеров Box () {
width = -1; // использовать -1 для указания
height = -1; // неинициализированного
depth = -1; // блока
}
// конструктор для куба Box(double len) {
width = height = depth = len;
}
// создать и возвратить объем
double volume() {
return width * height * depth;
}
}
class OverloadCons2 {
public static void main(String args[]} {
// создать блоки с использованием различных конструкторов
Box myboxl = new Box(10, 20, 15);
Box mybox2 = new Box();
Box mycube = new Box(7);
Box myclone = new Box(myboxl);
double vol;
// получить объем первого блока
vol = myboxl.volume();
System.out.println("Объем myboxl равен " + vol);
// получить объем второго блока
vol = mybox2.volume();
System.out.println("Объем mybox2 равен " + vol);
// получить объем куба
vol = mycube.volume();
System.out.println("Объем cube равен " + vol);
// получить объем клона
vol = myclone.volume();
System.out.println("Объем clone равен " + vol);
}
}
Когда вы начинаете создавать собственные классы, обычно нужно организовывать много форм конструкторов, что позволит образовывать объекты удобным и эффективным способом.