我试图理解我的代码的最后一条声明在Java中是非法的理由。请参阅下面的评论。
public class Rectangle {
private int height;
private int width;
public Rectangle(int height, int width) {
this.height = height;
this.width = width;
}
}
class ColoredRectangle extends Rectangle {
private String color;
public ColoredRectangle(int height, int width, String color) {
super(height, width);
this.color = color;
}
public String getColor() {
return color;
}
public static void main(String[] args) {
ColoredRectangle blueRectangle = new ColoredRectangle(2, 4, "blue");
Rectangle sameObjectDifferentType = blueRectangle;
((ColoredRectangle) sameObjectDifferentType).getColor(); //Will compile
sameObjectDifferentType.getColor(); //Won't compile
}
}
我知道我不应该使用这种设计,而应该使用其他构造函数。我知道getColor()
是“未在矩形中定义的”。尽管如此,我对这段代码的看法仍然是:sameObjectDifferentType是对同时为Rectangle和ColoredRectangle的对象的引用,因此无论我将引用声明为Rectangle还是ColoredRectangle,我都应该能够访问其所有成员。那么……为什么Java是这样设计的?
答案 0 :(得分:0)
fetchForums
进行这样的声明时,您明确地告诉编译器应将其视为Rectangle sameObjectDifferentType = blueRectangle;
。尽管在这种情况下它可能是Rectangle
,但这种保证消失并不会花费太多。
答案 1 :(得分:0)
在此行中,您声明sameObjectDifferentType
的类型为Rectangle
Rectangle sameObjectDifferentType = blueRectangle;
在更多真实的示例中,这将允许您具有几种不同的类型,并且希望以相同的方式进行处理。经典示例是CurrentAccount
,CheckingAccount
,SavingsAccount
,它们都是从Account
继承的。
假设您的银行业务应用程序具有用于查找帐户并找出帐户持有人的代码。该代码将只处理抽象的Account
类型。这意味着将来您引入StudentAccount
时,只要它继承自Account
,您就可以在当前处理StudentAccount
的所有地方使用Account
而无需更改代码。
假设您的示例中有一个FilledRectangle
和WireFrameRegtangle
。您可能有一个适用于所有矩形的calculateArea(Rectangle rect)
方法。
但是,要权衡这种功能和灵活性,您需要权衡的一点是,当您声明一个对象为超类类型时,您将无法直接处理子类的属性,因此
sameObjectDifferentType.getColor(); //Won't compile
但是,Java确实为您提供了一种通过强制转换返回子类的方法:
((ColoredRectangle) sameObjectDifferentType).getColor(); //Will compile
作为开发人员,您知道sameObjectDifferentType
实际上是ColoredRectangle
的幕后黑手,因此您可以安全地进行此投射。但是,如果这样做了
((FilledRectangle) sameObjectDifferentType).getFillPattern();
您最终将获得运行时ClassCastException
希望这会有所帮助。