Java 什么';对超类和子类的访问限制背后的原因是什么?

Java 什么';对超类和子类的访问限制背后的原因是什么?,java,inheritance,subclass,superclass,Java,Inheritance,Subclass,Superclass,我试图理解代码的最后一条语句在Java中是非法的原因。见下面的评论 public class Rectangle { private int height; private int width; public Rectangle(int height, int width) { this.height = height; this.width = width; } } 我知道我不应该使用这种设计,而是使用不同的构造函数。我知道getColor()是“未在矩形中定义的

我试图理解代码的最后一条语句在Java中是非法的原因。见下面的评论

public class Rectangle {

private int height;
private int width;

public Rectangle(int height, int width) {
    this.height = height;
    this.width = width;
  }

}

我知道我不应该使用这种设计,而是使用不同的构造函数。我知道
getColor()
是“未在矩形中定义的”。不过,我对这段代码的思考方式是:sameObjectDifferentType是对一个对象的引用,该对象既是一个矩形又是一个ColoredRectangle,因此无论我是将引用声明为Rectangle还是ColoredRectangle,我都应该能够访问它的所有成员。所以为什么Java设计成这样

Rectangle sameObjectDifferentType = blueRectangle;

当您做出这样的声明时,您明确地告诉编译器它应该被视为一个
矩形。在本例中,它可能是一个
彩色透视图
,但它不需要太多的时间就可以消失。

在这一行中,您声明
sameObjectDifferentType
是一个
矩形

Rectangle sameObjectDifferentType = blueRectangle;
在更真实的例子中,这将允许您有几种不同的类型,您希望以相同的方式处理它们。经典的例子是
CurrentAccount
CheckingAccount
SavingsAccount
,它们都是从
Account
继承的

假设您的银行应用程序具有查找帐户并找到帐户持有人的代码。该代码将只处理抽象的
帐户
类型。这意味着,将来当您引入
StudentAccount
时,如果它继承自
Account
,您可以在当前处理
Account
的所有地方使用
StudentAccount
,而无需更改代码

假设在您的示例中有一个
FilledRectangle
WireFrameRegtangle
。您可以有一个应用于所有矩形的
calculateArea(矩形矩形)
方法

然而,在这种能力和灵活性上的一个权衡是,当您将对象声明为超类类型时,您将失去直接处理子类属性的能力,因此

sameObjectDifferentType.getColor();  //Won't compile 
但是,Java确实为您提供了一种返回子类的方法,正如您通过强制转换注意到的:

((ColoredRectangle) sameObjectDifferentType).getColor(); //Will compile
作为一名开发人员,您知道
sameobjectdifferentittype
实际上是一个
coloredlectangle
,因此您可以安全地进行此转换。但是如果您这样做了

((FilledRectangle) sameObjectDifferentType).getFillPattern(); 
您将得到一个运行时ClassCastException


希望这有帮助。

color=this.color
应该是
this.color=color
。我知道getColor()是“未在矩形中定义的”。这完全正确<代码>getColor()
未在
矩形中定义。您第一次正确地考虑了它。如果您有另一个类是
Rectangle
并且有
getColor()
方法,会发生什么?现在我们甚至不能对这个表达式进行类型检查。否则Java将如何设计?这就是OOP的工作原理-并非所有的
Rectangle
s都是
ColoredRectangle
s。顺便说一句,
Rectangle
的构造函数是向后的:它从成员变量更新参数!谢谢@yinder,如果您满意,请点击旁边的勾号,将我的答案标记为已接受答案?
((FilledRectangle) sameObjectDifferentType).getFillPattern();