Java 什么';对超类和子类的访问限制背后的原因是什么?
我试图理解代码的最后一条语句在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()是“未在矩形中定义的
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();