例如,当我有一个类 Rectangle 和一个类 Square 时。如果类 Square 扩展了 Rectangle,则类 square 是类 Rectangle 的子类。现在说我有代码。 矩形形状 = new Square(5,6);
我将创建一个对象,但它会是 Rectangle 类型,但使用 square 的构造函数,还是 Square 的对象?,我的困惑始于 Square 类具有与 Rectangle 类相同的方法,但它将使用类中的方法正方形不是矩形类。那么我是否创建了 Square 对象,但类型为 Rectangle?
评论:每个人都因为知道正方形不能扩展矩形而生气,但这是我老师的例子,纯粹显示继承,事实上,最后他展示了如果我们使用这段代码,它会产生一个错误。
最佳答案
这让很多人感到困惑。让我尝试分解它。
当您说new Square
时,该对象是使用Square
构造函数创建的。该对象在其存在期间将具有 Square
类型。
当您声明一个 Rectangle
类型的变量时,即 Rectangle x;
或 Rectangle x = (anything);
您是在告诉编译器认为 x
(当它不为空时)将始终是对 Rectangle
或其任何子类(包括 Square)的引用
)。当您说 Rectangle x = new Square(...)
时,x
将是对 Square
的引用,它是一个 矩形
。 但是,x
稍后可能会被重新分配为非正方形
的其他矩形
。
这意味着,当您说 x.method(...)
时,编译器只允许您使用 Rectangle
中定义的方法,因为编译器只知道x
是一个Rectangle
或某个子类。如果您在 Square
中声明一个新方法,则无法在上述调用中使用它。
但是,如果x
仍然是对Square
的引用,那么当您调用Rectangle
中定义的方法时,程序实际上会运行您为 Square
编写的方法(如果您已覆盖 Rectangle
中的方法)。
也许这个例子会有所帮助。假设 Rectangle
声明 public
方法 aaa
和 bbb
。在 Square
中,您编写一个重写方法 aaa
,但不重写 bbb
,并声明一个新的公共(public)方法 ccc
.
Rectangle x = new Square(10);
Rectangle y = new Rectangle(5,6);
// assume that x and y aren't changed
x.aaa(); // runs the overriding method aaa in Square
y.aaa(); // runs the method aaa in Rectangle
x.bbb(); // runs the method in Rectangle, since it's not overridden. But
// if bbb calls aaa, then it will call the aaa in Square.
y.bbb(); // runs the method in Rectangle
x.ccc(); // illegal. Even though the object is actually a Square, the
// compiler isn't allowed to know that.
y.ccc(); // illegal
((Square)x).ccc(); // This is how you can get to the new method that you
// declared in Square. Even though the compiler doesn't know
// that x is a Square, when you use the cast, you tell the
// compiler that it's OK fo treat it as a Square, and to access
// the method defined only in Square.
((Square)y).ccc(); // Will throw ClassCastException at runtime, because
// y isn't a Square.
希望这有帮助。
关于 java 。类的类型与对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36368940/