类型检查和方法查找

时间:2019-04-05 17:28:12

标签: java

我对Java中类型检查和方法查找的功能感到困惑。

据我了解,类型检查是在编译时完成的,方法查找是在运行时完成的。

类型检查基于引用对象的声明类型,而方法查找则基于引用的实际类型。

因此,假设MyInt类是GaussianInt类的超类,如下所示:

class MyInt 
{ 
    private int n; 
    public myInt(int n)
    { 
        this.n = n;
    }
    public int getval()
    {
        return n;
    }
    public void increment(int n)
    { 
        this.n += n;
    }
    public myInt add(myInt N)
    { 
        return new myInt(this.n + N.getval());
    }
    public void show()
    { 
        System.out.println(n);
    }
}

class GaussInt extends MyInt 
{ 
    private int m; //represents the imaginary part
    public GaussInt(int x, int y)
    { 
        super(x); 
        this.m = y;
    }
    public void show()
    { 
        System.out.println( "realpart is: " + this.getval() +" imagpart is: " + m);
    }
    public int realpart() 
    { 
        return getval();
    } 
    public int imagpart() 
    {
        return m;
    }
    public GaussInt add(GaussInt z)
    { 
        return new GaussInt(z.realpart() + realpart(), z.imagpart() + imagpart()); 

}

并假设在main方法中我们具有以下内容:

GaussInt z = new GaussInt(3,4); 
MyInt b = z;
MyInt d = b.add(b)
System.out.println("the value of d is:"+ d.show());

最后,在print语句内的show语句中将使用哪种add方法?

据我了解,b被声明为MyInt,但实际上它是GuaussInt。类型检查器仅看到b为MyInt类型,并且具有add(MyInt),因此代码有意义并可以编译。

但是随后在运行时,方法查找发现b为GaussInt类型,并且它具有两个add()方法,因此它将通过查看方法签名使用add(GaussInt)方法,并生成一个GaussInt。但是d是MyInt类型,方法查找会认为它不起作用,然后返回add(Myint)吗?

程序的编译和运行背后的机制如何工作?

1 个答案:

答案 0 :(得分:1)

  

据我了解,b被声明为MyInt,但实际上,   高斯诠释

正确b的引用类型为MyInt,但它指向GaussInt类型的对象。

  

但是在运行时,方法查找发现b是类型   GaussInt,它有两个add()方法,因此它将使用add(GaussInt)   通过查看方法签名获得方法GaussInt。但   d是GaussInt类型,方法查找将认为它不起作用,然后   它会返回添加(Myint)吗?

由于GaussInt中的add方法采用的是GaussInt类型的引用,而不是MyInt类型的引用。因此b.add(b)将调用MyInt类型的add方法。由于gaussInt有两种添加方法,一种采用类型为MyInt的参数,另一种采用类型为GaussInt的参数。因此它将调用add的{​​{1}}方法。

您要实现的目标是方法替代。为了使它起作用,方法签名应该相同。也就是说,父类和子类方法在各个方面都应该匹配,除了子类方法的返回类型可以是父类方法的返回类型的myInt(superclass)

为了达到您提到的目的,即subtype应该调用b.add(b)的{​​{1}}方法,使两个类中add方法的参数类型相同。

您还应该了解动态多态性(运行时检查)和静态多态性(编译时类型检查)。