Если вы объявляете класс, производный от абстрактного класса, но хотите иметь возможность создания объектов нового типа, вам придется предоставить определения для всех абстрактных методов базового класса. Если этого не сделать, производный класс тоже останется абстрактным, и компилятор заставит пометить
Можно создавать класс с ключевым словом abstract даже тогда, когда в нем не имеется ни одного абстрактного метода. Это бывает полезно в ситуациях, где в классе абстрактные методы просто не нужны, но необходимо запретить создание экземпляров этого класса.
Класс Instrument очень легко можно сделать абстрактным. Только некоторые из его методов станут абстрактными, поскольку объявление класса как abstract не подразумевает, что все его методы должны быть абстрактными. Вот что получится:
А вот как выглядит реализация примера оркестра с использованием абстрактных классов и методов:
//. interfaces/music4/Musiс4 java // Абстрактные классы и методы package interfaces.music4; import polymorphism.music.Note, import static net mindview util Print *.
abstract class Instrument {
private int i; // Память выделяется для каждого объекта public abstract void play(Note n); public String whatO { return "Instrument"; } public abstract void adjustO,
}
class Wind extends Instrument { public void play(Note n) {
print("Wind playО " + n),
}
public String whatO { return "Wind"; } public void adjustO {}
}
class Percussion extends Instrument { public void play(Note n) {
printC'Percussion playO " + n).
}
public String whatO { return "Percussion", } public void adjustO {}
}
class Stringed extends Instrument { public void play(Note n) {
print ("Stringed playO " + n),
}
public String whatO { return "Stringed". } public void adjustO {}
}
class Brass extends Wind {
public void play(Note n) {
printCBrass.playO " + n);
}
public void adjustO { printC'Brass adjustO"), }
}
class Woodwind extends Wind { public void play(Note n) {
print("Woodwind playО " + n);
}
public String whatO { return "Woodwind", }
}
public class Music4 {
// Работа метода не зависит от фактического типа объекта. // поэтому типы, добавленные в систему, будут работать правильно:
static void tune(Instrument i) {
//
i.piay(Note MIDDLE_C),
}
static void tuneAll (Instrument!!] e) { for(Instrument i e) tune(i).
}
public static void main(String[] args) {
// Восходящее преобразование при добавлении в массив Instruments orchestra = { new WindO. new PercussionO. new StringedO. new BrassO. new WoodwindО
}.
tuneAl1(orchestra).
}
} /* Output Wind.pi ayО MIDDLE_C Percussion playO MIDDLE_C Stringed playO MIDDLE_C Brass playO MIDDLE_C Woodwind pi ayО MIDDLE_C */// ~
Как видите, объем изменений минимален.
Создавать абстрактные классы и методы полезно, так как они подчеркивают абстрактность класса, а также сообщают и пользователю класса, и компилятору, как следует с ним обходиться. Кроме того, абстрактные классы играют полезную роль при переработке программ, потому что они позволяют легко перемещать общие методы вверх по иерархии наследования.
Интерфейсы
Ключевое слово interface становится следующим шагом на пути к абстракции. Оно используется для создания полностью абстрактных классов, вообще не имеющих реализации. Создатель интерфейса определяет имена методов, списки аргументов и типы возвращаемых значений, но не тела методов.
Ключевое слово interface фактически означает: «Именно так должны выглядеть все классы, которые
Однако интерфейс представляет собой нечто большее, чем абстрактный класс в своем крайнем проявлении, потому что он позволяет реализовать подобие «множественного наследования» С++: иначе говоря, создаваемый класс может быть преобразован к нескольким базовым типам.
Чтобы создать интерфейс, используйте ключевое слово interface вместо class. Как и в случае с классами, вы можете добавить перед словом interface спецификатор доступа public (но только если интерфейс определен в файле, имеющем то же имя) или оставить для него дружественный доступ, если он будет использоваться только в пределах своего пакета. Интерфейс также может содержать поля, но они автоматически являются статическими (static) и неизменными (final).
Для создания класса, реализующего определенный интерфейс (или группу интерфейсов), используется ключевое слово implements. Фактически оно означает: «Интерфейс лишь определяет форму, а сейчас будет показано, как это
Классы Woodwind и Brass свидетельствуют, что реализация интерфейса представляет собой обычный класс, от которого можно создавать производные классы.