这个想法是避免测试对象类型的条件,例如
public void doThing() {
if (myObject instanceof ClassA)
doSomething();
else if (myObject instanceof ClassB);
doSomethingElse();
}
我们想要避免此类测试的原因是因为它们是我们代码中未来错误的来源。当一个新类被添加到我们的系统中时,所有这些测试都必须进行审查并可能进行更改。迟早,我们人类会犯错误,然后我们就会有错误的代码。此外,它使我们的代码更复杂,而且通常更慢。在这个简单的例子中,这并不明显,但如果我们以不同的方式测试一堆类型,它会是。
在这种情况下,myObject 是一个既继承ClassA
又ClassB
继承的类的实例;让我们调用那个父类ClassP
。所以我们可以避免像这样添加一个方法来ClassP
调用doSomething
class ClassP {
// lots of ClassP code
public void doSomething() {
// basic implementation of method
}
}
让我们假设这段代码适用于ClassA
,所以对于 ClassA 实例,我们可以只编写代码
myObject.doSomething();
但是因为ClassB
我们需要不同的行为,所以我们编码
class ClassB extends ClassP {
// lots of ClassB code
public void doSomething() {
// different implementation of method
}
}
所以现在我们可以做
myObject.doSomething();
例如ClassB
也。我们不再需要那个条件。
强大的是,此代码还将处理将来添加到继承层次结构中的新类型,而无需更改。所以如果我们现在添加一个类
class ClassC extends ClassP {
// lots of ClassC code
public void doSomething() {
// totally different implementation of method
}
}
然后
myObject.doSomething();
myObject
仍然有效,并且在为实例时调用新类中的方法ClassC
,甚至不需要重新编译!
有几种多态,参见维基百科:多态(计算机科学)和面向对象编程中的多态。正如您在这些页面上看到的那样,这是一个有争议的领域。
我们在这里使用的类型称为子类型多态,并且由于它可以实现的方式也称为动态绑定。