这不是标准术语,但作者似乎正在使用它来(尝试)让初学者可以使用它。 (这并不容易。)基本上,他们是说如果你有:
class Base {
public void baseMethod() {
// ...
}
}
class Derived extends Base {
public void derivedMethod() {
// ...
}
}
你可以这样做:
Base b = new Derived();
...因为 Base 类型定义的所有功能 (baseMethod) 在您分配的对象(Derived 的实例)上都可用。您“承诺”b 所指的对象将具有baseMethod,并且确实如此。
但你不能这样做:
Derived d = new Base();
...因为Derived 类型定义了您分配的对象(Base 实例)没有的特性(derivedMethod)。您“承诺”d 所指的对象将具有 derivedMethod,但事实并非如此,因此您“承诺太多”。
你的评论:
第二个例子中的转换是怎么来的?
它没有进入那个例子。强制转换不会改变对象是什么,只会改变你对它的引用。¹
但是假设你有这样的事情:
void someMethod(Base obj) {
if (obj instanceof Derived) { // Just an example, `instanceof` is usually
// an anti-pattern
Derived d = (Derived)obj;
// ...
}
}
该方法接收一个对象并且只有一个Base 对它的引用。但是随后代码检查并发现该对象实际上是Derived(或Derived 的子类),因此它使用强制转换来更改它所拥有的引用类型,以便它可以使用Derived 功能。所以选角就是以这种方式出现的。
再次注意,在十分之九的情况下,使用instanceof 是一种反模式。十分之九,您希望重构代码,以便将接口类型传递给仅定义代码所需功能的代码。第十种情况很少见。 :-)
第二次的施法总是成功吗?
只有当您确定该对象属于您要转换的类型或该类型的子类时。如果您不确定,投射它可能会抛出 ClassCastException。
¹ ...除了将基元(例如int)转换为它们的包装对象(例如Integer)的特殊情况,反之亦然。即使这样,它也不会更改对象,它只是创建一个对象(当转换为包装器类型时)或创建一个基元(当转换为基元类型时)。