colorprinter
не перестает быть экземпляром cp
при использовании оператора, наложенные на него, так его реализация public void drucke()
не меняет
Что вы выражаете с (p)colorprinter
кастинге вид контракт (интерфейс) вы ожидаете, что объект colorprinter
удовлетворит, что включает открытый метод с подписями public void drucke()
, но не какой-либо конкретной реализации.
И, кстати, эта отливка уже выполняется неявно при объявлении drucker
типа p
, так (p)
избыточна в p drucker = (p)colorprinter;
. p drucker = colorprinter;
хватит.
Here you can learn more about typecasting.
Имейте в виду, что лучше всего отказаться от абстрактных классов или интерфейсов и только @Override
(реализовать) абстрактные методы. Лучший дизайн вашего кода будет:
abstract class BasePrinter {
public void druckauftrag() {
// ...
drucke();
}
public void drucke();
}
class p extends BasePrinter {
public void drucke() {
System.out.println("B/W-Printer");
}
}
class cp extends BasePrinter {
public void drucke() {
System.out.println("Color-Printer");
}
}
Но, конечно, ограничения не всегда позволяют такого рода редизайн.Переходя базовые требования в качестве параметров конструктору (dependency injection) вместо расширения базового класса также может быть хорошей альтернативой:
interface Druckable {
void drucke();
}
class Druckauftrager {
Druckable dk;
Druckauftrager(Drukable dk){
this.dk = dk;
}
public void druckauftrag() {
// ...
dk.drucke();
}
}
class p implements Druckable {
public void drucke() {
System.out.println("B/W-Printer");
}
}
class cp implements Druckable {
public void drucke() {
System.out.println("Color-Printer");
}
}
Теперь, если вы хотите, чтобы выразить, что принтер требует или может иметь несколько возможностей печати (как и в цвете и ч/б), вы просто пишете класс с как много дополнительных Drukable свойств и параметров конструктора, как вы хотите, например:
class BlackAndWhiteOrColorPrinter {
p blackAndWhitePrintService;
cp colorPrintService;
Druckable selectedPrintService;
BlackAndWhiteOrColorPrinter (p blackAndWhitePrintService, cp colorPrintService){
this.blackAndWhitePrintService = blackAndWhitePrintService;
this.colorPrintService = colorPrintService;
this.selectedPrintService = blackAndWhitePrintService;
}
public void druckauftrag() {
// ...
selectedPrintService.drucke();
}
}
Таким образом, вы можете даже написать class MultiPrinter
с MultiPrinter(List<Druckable> printServices)
конструктора и добавить любое количество режимов печати в свой список служб печати : p
, cp
, и любая другая реализация Druckable
с ее public void drucke()
появится в будущем. Это также весьма практично, если вы хотите ввести модульное тестирование, поэтому вы можете предоставить объекты макета, которые вынуждают конкретные условия, которые вы хотите протестировать, например, druke()
, например, бросать PaperJamException
.
Для получения дополнительной информации о том, как интерфейсы, переопределение и наследование работы, см https://docs.oracle.com/javase/tutorial/java/IandI/usinginterface.html
BTW, acording к последней версии официального java code conventions guide, а также де-факто стандартом, классы в Java должны использовать CamelCase именования. Вы также можете значительно выиграть от использования семантичного именования во всех своих определениях, таких как BlackAndWhitePrinter blackAndWhitePrinter
и ColorPrinter colorPrinter
.
Немного nitpick: назовите свои классы прописными буквами для большей ясности. –
Никогда не используйте свой неанглийский родной язык, когда классы именования, mehtods и т. Д. Используйте английский camelCase. –
Тип класса - это определение того, как объект просматривается «внешними пользователями» (другими классами). Реализация метода привязана к экземпляру, и тип определяет только внешний cotract. – topr