为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

开满天机 2022-04-28 17:03:49
我试图了解我的代码在 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()是“未在 Rectangle 中定义”。尽管如此,我对这段代码的看法是:sameObjectDifferentType 是对一个既是 Rectangle 又是 ColoredRectangle 对象的引用,因此无论我将引用声明为 Rectangle 还是 ColoredRectangle,我都应该能够访问它的所有成员。那么......为什么Java是这样设计的?
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

在这一行中,您声明它sameObjectDifferentType是一种类型Rectangle

Rectangle sameObjectDifferentType = blueRectangle;

在更真实的示例中,这将允许您拥有几种不同的类型,您希望以相同的方式对待它们。经典的例子是CurrentAccountCheckingAccountSavingsAccount它都继承自Account.

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

假设你有一个FilledRectangleandWireFrameRegtangle在你的例子中。你可以有一个calculateArea(Rectangle rect)适用于所有矩形的方法。

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

sameObjectDifferentType.getColor();  //Won't compile

但是,Java 确实为您提供了一种返回子类的方法,正如您通过强制转换所指出的那样:

((ColoredRectangle) sameObjectDifferentType).getColor(); //Will compile

作为开发人员,您知道这sameObjectDifferentType确实是一个ColoredRectangle幕后花絮,因此您可以安全地进行此演员阵容。但是,如果您这样做了

((FilledRectangle) sameObjectDifferentType).getFillPattern();

你最终会得到一个运行时 ClassCastException

希望这可以帮助。


查看完整回答
反对 回复 2022-04-28
?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

Rectangle sameObjectDifferentType = blueRectangle;

当你做出这样的声明时,你明确地告诉编译器它应该被视为一个Rectangle. 虽然在这种情况下它可能是一个ColoredRectangle,但该保证消失并不需要太多。


查看完整回答
反对 回复 2022-04-28
  • 2 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信