Java的重载方法选择(Java overloading method selection)

2019-07-19 04:53发布

我试图让我的头一轮的Java如何选择哪个方法被执行:

//Example 1 prints Square:add(Figure)
Figure fs = new Square();
fs.add(fs);

//Example 2 prints Square:add(Figure)
Rectangle rs = new Square();
rs.add(fs);

//Example 3 prints Rectangle:add(Rectangle). Expected Square:add(Square)
rs.add(new Square());

//Example 4 prints Rectangle:add(Rectangle). Expected Square:add(Figure)
Square ss = new Square();
ss.add(rs);

class Figure
{
    public void add(Figure f){ System.out.println("Figure:add(Figure)"); }
}

class Rectangle extends Figure
{
    @Override
    public void add(Figure f){ System.out.println("Rectangle:add(Figure)"); }
    public void add(Rectangle r){ System.out.println("Rectangle:add(Rectangle)"); }
}

class Square extends Rectangle
{
    @Override
    public void add(Figure f){ System.out.println("Square:add(Figure)"); }
    public void add(Square s){ System.out.println("Square:add(Square)"); }
}

我学到的东西在这里是

  • 方法得到签名的基础上确定的编译时间数据类型
  • 调用实际方法取决于动态类型的方法被称为所述对象的。

在此基础上,前两个电话的结果是如预期。 不过,我不明白,例如3和4的结果。

这似乎在被指定的Java语言规范 ,但我不明白。

Answer 1:

不过,我不明白,例如3和4的结果。

好吧,让我们来看看他们的个人。

实施例3

//Example 3 prints Rectangle:add(Rectangle). Expected Square:add(Square)
rs.add(new Square());

最重要的部分是在编译时类型的表达式的rsnew Square()

rs仅声明为Rectangle ,所以编译器将着眼于通过声明的方法Rectangle和其超:

public void add(Figure f)
public void add(Rectangle r)

类型表达的new Square()Square ,所以这两种方法都适用 -但第二个是更具体的。

所以编译器会调用add(Rectangle) ,对象上rs指。 这就是它的编译时侧。

在执行时,值rs是指一个实例Square -但Square不会覆盖add(Rectangle)所以挑的方法是在执行Rectangle

public void add(Rectangle r){ System.out.println("Rectangle:add(Rectangle)"); }

实施例4

//Example 4 prints Rectangle:add(Rectangle). Expected Square:add(Figure)
Square ss = new Square();
ss.add(rs);

再次,让我们考虑涉及到的编译时类型... ss是类型的Square ,和rs的类型的Rectangle (编译时类型,记不清了)。

通过声明的方式Square和其超有:

public void add(Figure f)
public void add(Rectangle r)
public void add(Square s)

为一体的编译时类型rsRectangle (未Square ),前两种方法都适用,但第三个不是。 因此,再次add(Rectangle)在编译时采摘(因为它是更具体的比add(Figure) )。

再次,的执行时间类型ssSquare ,其不会覆盖add(Rectangle) ,所以在实施Rectangle被使用。

让我知道你在这里什么是混乱的 - 如果你能具体哪些部分,这将是巨大的。



Answer 2:

rs.add(new Square());

RS的声明类型为矩形。 因此,着眼于矩形的方法和所有超服用或方作为参数与广场相兼容的类型。 最具体的一个是add(Rectangle)因为广场是矩形,并且由于矩形比图更加具体。

Square ss = new Square();
ss.add(rs);

寻找一个方法add(Rectangle)在广场和所有超类。 Rectangle.add(Rectangle)被选择,因为Square.add(Square)不适用(一个矩形不是正方形),和Square.add(Figure)是较不具体。



文章来源: Java overloading method selection