📜  可以在Java中重载或重写静态方法吗

📅  最后修改于: 2020-03-19 13:29:29             🧑  作者: Mango

让我们首先定义重写和重载。

重写:重写是OOP语言(例如Java)的一项功能,与运行时多态性有关。子类(或派生类)在超类(或基类)中提供方法的特定实现。
将在运行时确定要执行的实现,并根据用于调用的对象进行决策。请注意,这两种方法的签名必须相同。有关详细信息,请参见 Java中的Override
重载:重载也是Java等OOP语言的功能,与编译时(或静态)多态性有关。此功能允许不同的方法具有相同的名称,但具有不同的签名,尤其是输入参数的数量和输入参数的类型。请注意,在C++和Java中,都不能根据返回类型重载方法。

我们可以重载静态方法吗?
答案是“是”。我们可以使用名称相同但输入参数不同的两个或多个静态方法。例如,考虑以下Java程序。

// 文件名 Test.java
public class Test {
    public static void foo() {
        System.out.println("Test.foo() 被调用 ");
    }
    public static void foo(int a) {
        System.out.println("Test.foo(int) 被调用 ");
    }
    public static void main(String args[])
    {
        Test.foo();
        Test.foo(10);
    }
}

输出:

Test.foo() 被调用
Test.foo(int) 被调用

我们可以仅通过static关键字重载不同的方法吗?
如果两个方法仅在静态关键字上有所不同(参数数量和参数类型相同),则无法重载Java中的两个方法。例如,请参见以下Java程序。这种行为在C++中是相同的。

// 文件名 Test.java
public class Test {
    public static void foo() {
        System.out.println("Test.foo() 被调用 ");
    }
    public void foo() { // Compiler Error: cannot redefine foo()
        System.out.println("Test.foo(int) 被调用 ");
    }
    public static void main(String args[]) {
        Test.foo();
    }
}

输出:编译器错误,无法重新定义foo()

我们可以冲那些Java中的静态方法吗?
我们可以在子类中声明具有相同签名的静态方法,但由于不会存在任何运行时多态性,因此不认为它是重写的。因此,答案是“否”。
如果派生类定义的静态方法与基类中的静态方法具有相同的签名,则派生类中的方法会将方法隐藏在基类中。

// Java静态方法不能被重写
// 父类
class Base {
    、、静态方法
    public static void display() {
        System.out.println("基类的静态或类");
    }
     // 非静态方法
     public void print()  {
         System.out.println("基类的非静态或实例");
    }
}
// 子类
class Derived extends Base {
    // 这个方法隐藏基类中的display()
    public static void display() {
         System.out.println("子类的静态或类");
    }
    // 重写父类的print()
    public void print() {
         System.out.println("子类的非静态或实例");
   }
}
// 测试代码
public class Test {
    public static void main(String args[ ])  {
       Base obj1 = new Derived();

       obj1.display();

       obj1.print();
    }
}

输出:

基类的静态或类
子类的非静态或实例

以下是Java中方法重写和静态方法的一些重要要点。
1)对于类(或静态)方法,根据引用类型而不是根据所引用的对象调用方法,这意味着方法调用是在编译时决定的。
2)对于实例(或非静态)方法,该方法是根据要引用的对象的类型而不是引用的类型来调用的,这意味着方法调用是在运行时确定的。
3)实例方法不能重写静态方法,并且静态方法不能隐藏实例方法。例如,以下程序有两个编译器错误:

/* Java代码,展示实例方法不能重写静态方法
// 父类
class Base {

    public static void display() {
        System.out.println("基类的非静态或实例");
    }
     
     public void print()  {
         System.out.println("基类的非静态或实例");
    }
}
// 子类
class Derived extends Base {
    // 编译错误
    public void display() {
        System.out.println("子类的静态或类");
    }
    // 编译错误
    public static void print() {
        System.out.println("子类的非静态或实例");
   }
}

4) 在子类(或派生类)中,我们可以重载从超类继承的方法。这样的重载方法既不会隐藏也不会覆盖超类方法-它们是子类独有的新方法。

参考:http ://docs.oracle.com/Javase/tutorial/Java/IandI/override.html