我不太确定如何表达这个问题,但是希望示例可以使它更加清楚。我正在尝试找出一种不被调用的实现抽象方法的最佳方法(什么也不做),我很好奇我当前的方法是否完全正确。
abstract class Vehicle {
void doSomething() {
if (this.getClass() instanceof Chevy) {
operateOnCar();
}
}
abstract void operateOnCar();
}
class Chevy extends Vehicle {
@Override
void operateOnCar() {
print("Doing something to a car")
}
}
class HarleyDavidson extends Vehicle {
@Override
void operateOnCar() {
throw Exception("This isn't a car")
}
}
我能想到的另一种方法是让HarleyDavidson
类实现operateOnCar()
,但绝对不做任何事情-即,一个空的方法主体。这可能更好吗?也许这些都不是可行的例子,我应该重新考虑我的设计。谢谢!
编辑:试图使我的例子更清楚
答案 0 :(得分:2)
我正在尝试找出实施其中一种的最佳方法 抽象方法不被调用(不执行任何操作)
断言不应调用方法与断言不应执行任何操作完全不同。此外,不管抽象性如何,都无法在超类上定义方法,因此无法调用任何子类的任何实例。因此,对“不执行任何操作”替代方案进行一些更改是一个更好的选择。
当甚至不需要提供返回值的时候什么也不做的方法有什么困难呢?这是什么都不做的方法:
void isCar() {
// empty
}
在这一点上,我还应该观察到,大多数Java程序员都希望一个名为isCar
的方法返回一个boolean
,以指示对其进行调用的对象是否是“汽车”,无论在上下文中表示。令人惊讶的是,这样的方法被声明为不返回任何内容,甚至可能更令人惊讶的是它写入了System.out
。
答案 1 :(得分:2)
您正在模糊抽象类及其具体实现的职责。您的Employee
方法证明了这一点。
doSomething
您的抽象类应该不在乎它是什么实例;只有void doSomething() {
if (this.getClass() instanceof Chevy) {
operateOnCar();
}
}
类需要对此做些事情。
这可能就是为什么您对Chevy
方法感到困惑的原因。 operateOnCar
是Car
,但并非所有Vehicle
都是Vehicle
。您可能拥有卡车,货车,机车,轮船,飞机...所有这些都是它们自己的交通工具,但绝对不支持Car
方法。
这可能与重命名方法一样简单。您绝对可以操作或修理车辆。您只想在继承链的更高级别上保持尽可能不可知。
答案 2 :(得分:2)
如果创建一个类,则该类(包括其派生类)应仅具有与该类相关的属性/方法。如果属性/方法不适合,则不应将其放在类中。
那么如何将OperateOnCar放置在某处:使用策略模式,这是一种常见的设计模式。
比起使用操作OperateVehicle来创建一个OperatableOnVehicle界面。对于车辆,它将被实施,而对于HarleyDavidson,则将不被实施。
尽量避免使用“汽车”一词。
在互联网上可以找到许多有关该策略模式的示例,因此请使用google了解有关其背景的更多信息。
答案 3 :(得分:1)
我认为如果调用此方法的对象抛出以下异常:
throw Exception(“仅当汽车是雪佛兰时,才应调用此方法”)
最好打印出它不是汽车。顾名思义,该方法应返回boolean
Chevy
是汽车吗?是的-返回true
并告知结果HarleyDavidson
是汽车吗?不,不是-返回false
并通知Bicycle
是汽车吗?不,绝对不是。是车吗?是。是否有时间询问是否是汽车?为什么不呢?顺便问一下,您是否考虑过以下层次结构?
Vehicle
<-Car
<-Chevy
Vehicle
<-(Motocycle
)<-HarleyDavidson