Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么在某些父类上未选择子类类型的参数重载_Java - Fatal编程技术网

Java 为什么在某些父类上未选择子类类型的参数重载

Java 为什么在某些父类上未选择子类类型的参数重载,java,Java,我希望equals(Imp1 o)会被选为a.equals(b)和b.equals(a)的最佳候选者,为什么这里不是这样 更详细地说,这个代码输出两次假,我想知道为什么? a和b持有Imp1对象,因此使用Imp1实例作为参数调用equals应该调用equals(Imp1 o),这比equals(object o)更适合,但我看到正在调用equals(object o),最后,代码将两次输出false,而不是两次输出true。方法重载解析由参数的编译时类型决定,因为编译器在编译时选择了最佳匹配的方

我希望
equals(Imp1 o)
会被选为
a.equals(b)
b.equals(a)
的最佳候选者,为什么这里不是这样

更详细地说,这个代码输出两次假,我想知道为什么?
a和b持有Imp1对象,因此使用Imp1实例作为参数调用equals应该调用
equals(Imp1 o)
,这比
equals(object o)
更适合,但我看到正在调用
equals(object o)
,最后,代码将两次输出false,而不是两次输出true。

方法重载解析由参数的编译时类型决定,因为编译器在编译时选择了最佳匹配的方法签名

只有当传递给方法的参数的编译时类型为
Imp1
Imp1
的子类时,才能选择
equals(Imp1 o)

a
不符合此条件,因此
b.equals(a)
调用
对象的
equals

public class Imp1 implements Inter1 {
    private int num;

    @Override
    public void apply() {
        num++;
    }

    public void doubler() {
        num = num * 2;
    }

    public boolean equals(Imp1 o) {
        if (!(o instanceof Imp1))
            return false;
        return o.num == num;
    }

    public int getNum() {
        return num;
    }

    public static void main(String[] args) {
        final Inter1 a = new Imp1();
        final Imp1 b = new Imp1();
        a.apply();
        b.apply();
        System.out.println("a equals b " + a.equals(b));
        System.out.println("b equals a " + b.equals(a));
    }

}
至于
a.equals(b)
,由于
a
的编译时类型不是
Imp1
,它不能调用
equals(imp1o)
方法(除非将其强制转换为
Impl1
),因此它只能选择
对象的
equals

public class Imp1 implements Inter1 {
    private int num;

    @Override
    public void apply() {
        num++;
    }

    public void doubler() {
        num = num * 2;
    }

    public boolean equals(Imp1 o) {
        if (!(o instanceof Imp1))
            return false;
        return o.num == num;
    }

    public int getNum() {
        return num;
    }

    public static void main(String[] args) {
        final Inter1 a = new Imp1();
        final Imp1 b = new Imp1();
        a.apply();
        b.apply();
        System.out.println("a equals b " + a.equals(b));
        System.out.println("b equals a " + b.equals(a));
    }

}

将调用
equals(Imp1 o)

问题在于您没有真正覆盖对象超类的equals

这是正确的方法:

System.out.println("a equals b " + ((Imp1)a).equals(b));
public类Imp1实现Inter1{
私有整数;
@凌驾
公开无效申请(){
num++;
}
公共空位倍增器(){
num=num*2;
}

@重写//那么a.equals(b)呢但是,java重写是C++中的虚拟术语,这意味着需要调用的实际方法是实例类而不是引用类型。class@OfekRon但是,为了使
Imp1
中的方法重写其祖先类中的任何方法,该方法必须与e祖先类。
Imp1
的唯一祖先类是
Object
,而
Object
没有一个
equals(imp1o)
方法。您希望实现的
equals
方法覆盖对象中的
equals
方法,但事实并非如此。使用
@Override
注释可以帮助您抓住这种误解。
public class Imp1 implements Inter1 {
    private int num;

    @Override
    public void apply() {
        num++;
    }

    public void doubler() {
        num = num * 2;
    }

    @Override  //<---------------need to be implemented from the interface!
    public boolean equals(Inter1 o) {//<----the class must to be from the specific interface!!! 
        if (!(o instanceof Imp1))
            return false;
        return ((Imp1)o).num == num;//<-----must to cast the object to the specific object in the "if"
    }

    public int getNum() {
        return num;
    }

    public static void main(String[] args) {
        final Inter1 a = new Imp1();
        final Imp1 b = new Imp1();
        a.apply();
        b.apply();
        System.out.println("a equals b " + a.equals(b));
        System.out.println("b equals a " + b.equals(a));
    }

}