Java重载方法选择 [英] Java overloading method selection

查看:158
本文介绍了Java重载方法选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解Java如何选择执行哪种方法:

I'm trying to get my head round how Java selects which method is executed:

//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的结果。

Based on that, the result of the first two calls is as expected. However, I don't understand the result of example 3 and 4.

似乎在 java语言规范,但我不明白。

推荐答案


但是,我不理解示例3和4的结果。

However, I don't understand the result of example 3 and 4.

好的,让我们分别看看它们。

Okay, let's look at them individually.

示例3

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

重要的部分是编译时类型的表达式 rs new Square()

The important parts are the compile-time types of the expressions rs and new Square().

rs 仅声明为 Rectangle ,因此编译器将查看 Rectangle 及其超类:

rs is only declared as Rectangle, so the compiler will look at the methods declared by Rectangle and its superclasses:

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

表达式的类型 new Square() Square ,因此两种方法都适用 - 但第二种方法更具特定

The type of the expression new Square() is Square, so both methods are applicable - but the second one is more specific.

因此编译器将在 rs 引用的对象上调用 add(Rectangle)至。这是编译时的一面。

So the compiler will call add(Rectangle) on the object that rs refers to. That's it for the compile-time side.

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

At execution time, the value of rs refers to an instance of Square - but Square doesn't override add(Rectangle) so the method picked is the implementation in 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 (编译时类型,请记住)。

Again, let's consider the compile-time types involved... ss is of type Square, and rs is of type Rectangle (compile-time types, remember).

Square 声明的方法及其超类是:

The methods declared by Square and its superclasses are:

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

作为编译时类型 rs 只有 Rectangle (不是 Square ),前两种方法适用,但第三种方法不是。因此,再次在编译时选择 add(Rectangle)(因为它比 add(图)更具体) 。

As the compile-time type of rs is only Rectangle (not Square), the first two methods are applicable, but the third isn't. Therefore, again, add(Rectangle) is picked at compile time (as it's more specific than add(Figure)).

同样, ss 的执行时间类型是 Square ,它不会覆盖 add(Rectangle),因此使用 Rectangle 中的实现。

Again, the execution time type of ss is Square, which doesn't override add(Rectangle), so the implementation in Rectangle is used.

如果此处的任何内容令人困惑,请告诉我 - 如果您可以具体说明哪一部分会很棒。

Let me know if anything in here is confusing - if you can be specific about which part, that would be great.

这篇关于Java重载方法选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆