2 回答
TA贡献1846条经验 获得超7个赞
仅仅因为一个类不能被实例化并不意味着你不能得到它的一个实例。
在您的示例中,您所做的只是将其转换为 Graphics 层次结构中的另一个类。
这是一个例子。
public class AbstractDemo {
public static void main(String[] args) {
Concrete c = new Concrete();
AClass a = (AClass) c;
a.me();
}
}
abstract class AClass {
public void me() {
System.out.println("Abstract parent");
}
}
class Concrete extends AClass {
}
TA贡献1825条经验 获得超6个赞
一个类是抽象的只是意味着你不能直接创建这样一个类。一旦有了这样的类,就可以对其进行强制转换,使其看起来像是它的任何子类。换句话说,所有“抽象”意味着你不能做:
SomeAbstractClass obj = new SomeAbstractClass(...);
你可以引用一个Graphics2D对象,就像你的例子一样,但是如果你要求 Java 告诉你对象的真实类型,它实际上永远不会是一个Graphics2D对象。从这段代码中,您不能确定所讨论对象的真实类型也是一个Graphics对象。这可能再次是对真实对象的子类的引用,例如 maybeMyGraphicsObject或类似的东西。
这就是多态性的全部意义和威力。一旦你创建了一个对象,它的行为就像它的任何子类一样,并且可以通过向上转换将它视为任何这些子类的纯实例。
下面是一些代码,指出向上转型的对象的标识会发生什么:
abstract class Abstract {
public void whatAmI() {
System.out.println("I'm Abstract");
}
}
class Concrete extends Abstract {
@Override
public void whatAmI() {
System.out.println("I'm Concrete");
}
}
public class X {
public static void main(String[] args) {
// This won't compile. That's what it means for "Abstract" to be abstract.
// Abstract abs = new Abstract();
// You can create a Concrete, and then upcast it to an Abstract reference...
Concrete concrete = new Concrete();
Abstract abs = (Abstract)concrete;
// But it's stll really a Concrete
System.out.println(abs.getClass().getName());
// And it will still act like a Concrete if Concrete has overridden one of Abstract's methods.
abs.whatAmI();
}
}
结果:
org.littleshoot.proxy.inlet.Concrete
I'm Concrete
请注意,如果您向 Java 询问对象的类型,即使您已经通过抽象引用询问了对象的类型,它仍然是具体的。另请注意,如果您在抽象类上调用已在具体中被覆盖的方法,则将调用具体的版本。
添加回答
举报