我无法弄清楚访问子类的方法与使用子类(Point)的对象的静态类型使用基类(Object)进行覆盖之间的区别。 例如:
public class Point {
int x, y;
...
public boolean equals(Object o){
...
}
public boolean equals(Point p){
...
}
}
Object o = new Object();
Point p = new Point(3,4);
Object op = new Point(3,4);
// here the static type is Point and the dynamic type is point, in this case
// the equals() method that we choose and gets overwrriten depends on the
// parameter type that is passed.
p.equals(o);
p.equals(p);
p.equals(op);
// here however the static type is Object so we initially look at the equals()
// method in our Object class during compile time and check its parameter type
// which is Object, thus if we overwrite
// the equals() method we will pick the one that has a type Object parameter.
// Since the dynamic type of our object is Point, when we are at run time
// we will look for the equals() method in Point that matches with the
// method type Object parameter.
op.equals(o);
op.equals(op);
op.equals(p);
我没有看到的是为什么我想使用后者而不是前者来指定我想要覆盖的方法?前者取决于类型参数,而后者取决于对象的静态类型的类型参数。我只是没有看到使用Basetype obj = new Subclasstype()来访问和重写我的子类中的方法的好处。它看起来更复杂,并且该对象只能用于访问基类中子类中的方法实例,而不能用于子类中的任何其他方法。
答案 0 :(得分:3)
public boolean equals(Point p){
...
}
上述方法与equals(Object)
无关,除了共享名称equals
。它不会覆盖它,不能从Object
类型的变量调用它,Object
没有定义它的合约。
写作时
op.equals(p);
您正在调用Object
类型的方法。该类型中唯一称为equals
的方法是equals(Object)
,此选项是永久。运行时只能提供equals(Object)
的不同覆盖,但它永远不会将调用路由到equals(Point)
。
同样,当你写
p.equals(op);
编译器将再次看到您使用静态类型为equals
的参数调用Object
,并选择equals(Object)
。
答案 1 :(得分:1)
我认为你搞砸了一些概念,所以让我解释一下:
Object op = new Point(3,4);
变量o
和p
的行为很明确,因此我将重点关注op
:它是一个类型为Object
的变量,这意味着您可以使用在该类中声明的所有方法。您不能使用equals(Point p)
方法,因为它不存在于Object。但是,与此同时,方法的行为由它自己的实例给出,而不是由指向它的变量给出,因此op
指向Point实例和equals(Object)
方法已被覆盖,因此该方法的行为由类Point
给出。