Java 它是重载还是重写?

Java 它是重载还是重写?,java,overloading,overriding,Java,Overloading,Overriding,我有一个代码,我无法得到为什么输出将是“长子午线轮胎”。有人能帮我理解这个代码吗 class Tyre { public void front() throws RuntimeException { System.out.println("Tire"); } public void front(long a) { System.out.println("Radial Tire with long"); } } class Tes

我有一个代码,我无法得到为什么输出将是“长子午线轮胎”。有人能帮我理解这个代码吗

class Tyre {
    public void front() throws RuntimeException {
        System.out.println("Tire");
    }

    public void front(long a) {
        System.out.println("Radial Tire with long");
    }
}

class TestSolution extends Tyre {
    public void front() {
        System.out.println("Radial Tire");
    }
    public void front(int a) throws RuntimeException {
        System.out.println("Radial Tire with int");
    }


public static void main(String... args) {
        Tyre t = new TestSolution();
        int a = 10;
        t.front(a);

}

}

main
中没有发生重写

t
的静态(编译时)类型是
tire
,因此,由于方法重载解析是由实例的编译时类型决定的,因此编译器可以选择的唯一
front
方法是基类
tire
中声明的方法:

public void front()
public void front(long a)
只有后者(
public void front(long a)
)与调用
t.front(a)
的参数匹配,并且该方法不被子类重写。因此,将显示长的子午线轮胎

调用
((TestSolution)t.front(a)
将调用子类的方法-
public void front(int a)

front
TestSolution
中未被重写,而是被重载

您可以将重载函数视为完全不同的函数,就像具有不同名称的函数一样


因此
t.front(a)
将调用
Tyre
中的一个,其中
a
隐式转换为
long
,因此如果我们使用定义

重载是指具有相同名称但参数数量或顺序不同的方法

重写是指具有相同名称、相同参数数以及所述规则的方法

因此,在您的情况下,
front
方法在类
Tyre
TestSolution

方法
front()
from
Tyre
类在类
TestSolution
中被重写


对于方法
front(long a)
front(int a)
一般规则:如果我有一个类的变量,我只能访问该类中定义的方法和组件

唯一的特殊情况是:

  • 在超类和子类中都有一个组件或方法(重写)
  • 您有一个超类的变量和一个子类的对象(您的案例)
  • 在这些情况下,您可以遵循以下规则:

  • 对于组件,变量的类型决定使用哪个
  • 对于对象类型所执行的方法(后期绑定)

  • 在您的情况下,如前所述,该方法不会被覆盖,因此您无法应用最后一条规则。

    让我们了解和之间的区别

    超载:

    Java编程语言支持重载方法,Java可以区分具有不同方法签名的方法。这意味着,如果类中的方法具有不同的参数列表,则它们可以具有相同的名称

    覆盖:

    子类中的实例方法与超类中的实例方法具有相同的签名(名称,加上其参数的编号和类型)和返回类型,将覆盖超类的方法

    轮胎
    声明了
    front()
    方法,参数为
    long

    TyreSolution
    声明了
    front()
    方法,并将
    int
    作为参数

    由于方法签名不同,
    TyreSolution
    重载
    Tyre
    front()
    方法

    public void front(long a) throws RuntimeException {
        System.out.println("Radial Tire with long in TestSolution");
    }
    
    如果将
    TyreSolution
    front()
    的签名更改为接受
    long
    值作为输入参数,而不是
    int
    ,则
    TyreSolution
    覆盖
    轮胎的
    front()
    方法

    e、 g.
    TestSolution
    类定义
    front()
    方法

    public void front(long a) throws RuntimeException {
        System.out.println("Radial Tire with long in TestSolution");
    }
    
    输出:

    Radial Tire with long in TestSolution
    

    此处没有重写。如果您可以将
    @Override
    添加到方法中,而不会导致编译器错误,则您正在重写该方法。请注意,添加注释是一个好主意。这不是重写:)谢谢,但有一件事TestSolution也扩展了Tyre,那么它也会被重写吗?不。被重写的函数必须具有相同的签名。这意味着函数名和参数类型必须完全匹配。返回类型允许一定的灵活性,但这超出了这里的问题范围。感谢Eran,但是TestSolution确实包含重写的前端(int a),那么为什么它适用于在super class中定义的前端呢?@Arzoo
    void front(int a)
    不会重写基类中的任何方法,因为基类没有具有这种签名的方法。因此,
    void front(int a)
    不会被覆盖。如果基类中有一个
    void front(int a)
    方法,TestSolution中的
    void front(int a)
    方法会被执行,这是由于重写。好的,你是对的,我错过了那一分钟的细节,谢谢Eran:-)