假设我有两个类,其中子类继承自(扩展)超类。
有什么区别:
SuperClass obj1 = new SubClass();
和:
SubClass obj2 = new SubClass();
两者都将查看超类的构造函数并对其进行初始化(显然是正确的)。两者都可以访问超类实现。但是一个是(据我所知)包装在超类中的子类(第一个示例),另一个是子类对象(第二个示例)。
这将如何影响代码的运行和解释方式?
关于这两个对象的不同之处,开发人员需要注意哪些现实问题?
提前感谢您的帮助!
假设我有两个类,其中子类继承自(扩展)超类。
有什么区别:
SuperClass obj1 = new SubClass();
和:
SubClass obj2 = new SubClass();
两者都将查看超类的构造函数并对其进行初始化(显然是正确的)。两者都可以访问超类实现。但是一个是(据我所知)包装在超类中的子类(第一个示例),另一个是子类对象(第二个示例)。
这将如何影响代码的运行和解释方式?
关于这两个对象的不同之处,开发人员需要注意哪些现实问题?
提前感谢您的帮助!
将其初始化为超类的唯一区别是,如果子类实现具有超类没有的方法,则无法通过此对象引用访问它们。
但是“在内部”,这仍然是子类的一个实例;因此,如果您调用超类中定义的方法但子类已覆盖它,则调用的是子类的方法:JVM 从更具体到更通用查找方法。
作为一个复杂的例子,让我们以Object
and为例String
:
final Object o = "Hello!"; // in fact this calls new String("Hello!")
o.toString(); // <-- uses String's .toString(), not Object's
// Can't do that: String defines .subString() but Object does not
o.subString(1);
想想编译器知道什么以及运行时知道什么以及一个简单的例子可能会有所帮助:
public class Product {
public double getPrice() {...}
}
public class Book extends Product() {
public int getPageCount() {...}
}
and a simple program:
Product p = new Product();
p.getPrice(); // OK
p.getPageCount(); // compiler error
Book b = new Book();
b.getPrice(); // OK
b.getPageCount(); // OK
Product pb = new Book();
pb.getPrice(); // OK
pb.getPageCount(); // compiler error
// but we can still use the getPageCount() of pb;
((Book)pb).getPageCount(); // compiles
// however if pb was not a Book then you would get a runtime error (ClassCastException)
您可以通过以下方式测试实际课程:
if (pb instanceof Book) {
((Book)pb).getPageCount();
}
这在开发类时通常是必要的,但如果您的代码有很多,instanceof
则可能需要重新考虑。
SuperClass obj1 = new SubClass();
你在这里看到的是一种替代性。这意味着,假设您创建了 , 的另一个子SuperClass
类SiblingClass
。如果不使用超类引用类型,我们将不得不更改更多可能想要使用它的代码、getter 和 setter、集合。通过将它们引用为超类型,您需要做的就是SiblingClass
在构造时传入新对象。