Java 可以重载或重写静态方法吗
让我们先定义一下Overloading和Overriding。
Overriding :Overriding是像Java这样的OOP语言的一个特点,与运行时多态性有关。一个子类(或派生类)为超类(或基类)中的一个方法提供特定的实现。
要执行的实现是在运行时决定的,根据调用的对象来决定。注意,两个方法的签名必须是相同的。详情请参考《Java中的重载》。
重载 :重载也是像Java这样的OOP语言的一个特点,与编译时(或静态)多态性有关。这个特性允许不同的方法有相同的名字,但有不同的签名,特别是输入参数的数量和输入参数的类型。请注意,在C++和Java中,方法不能根据返回类型进行重载。
我们可以重载静态方法吗?
答案是 “可以”。我们可以有两个或多个名称相同的静态方法,但输入参数不同。例如,考虑下面的Java程序。
// filename Test.java
public class Test {
public static void foo() {
System.out.println("Test.foo() called ");
}
public static void foo(int a) {
System.out.println("Test.foo(int) called ");
}
public static void main(String args[])
{
Test.foo();
Test.foo(10);
}
}
输出
Test.foo() called
Test.foo(int) called
在Java中,如果两个方法仅有静态 关键字 的不同,我们不能重载它们(参数数量和参数类型相同)。请看下面这个Java程序的例子。这种行为在C++中也是一样的(见本文第2点)。
// filename Test.java
public class Test {
public static void foo() {
System.out.println("Test.foo() called ");
}
public void foo() { // Compiler Error: cannot redefine foo()
System.out.println("Test.foo(int) called ");
}
public static void main(String args[]) {
Test.foo();
}
}
输出
Compiler Error, cannot redefine foo()
我们可以在java中覆盖静态方法吗?
我们可以在子类中声明具有相同签名的静态方法,但这不被视为覆盖,因为不会有任何运行时多态性。因此答案是 “不能”。
如果一个派生类定义的静态方法与基类中的静态方法具有相同的签名,那么派生类中的方法就会被基类中的方法所隐藏。
/* Java program to show that if static method is redefined by
a derived class, then it is not overriding. */
// Superclass
class Base {
// Static method in base class which will be hidden in subclass
public static void display() {
System.out.println("Static or class method from Base");
}
// Non-static method which will be overridden in derived class
public void print() {
System.out.println("Non-static or Instance method from Base");
}
}
// Subclass
class Derived extends Base {
// This method is hidden by display() in Base
public static void display() {
System.out.println("Static or class method from Derived");
}
// This method overrides print() in Base
public void print() {
System.out.println("Non-static or Instance method from Derived");
}
}
// Driver class
public class Test {
public static void main(String args[ ]) {
Base obj1 = new Derived();
// As per overriding rules this should call to class Derive's static
// overridden method. Since static method can not be overridden, it
// calls Base's display()
obj1.display();
// Here overriding works and Derive's print() is called
obj1.print();
}
}
输出
Static or class method from Base
Non-static or Instance method from Derived
以下是Java中方法覆盖和静态方法的一些要点。
1) 对于类(或静态)方法,根据引用的类型来调用方法,而不是根据被引用的对象,这意味着方法调用在编译时决定。
2) 对于实例(或非静态)方法,方法的调用是根据被引用对象的类型,而不是根据引用的类型,这意味着方法的调用是在运行时决定的。
3) 一个实例方法不能覆盖一个静态方法,一个静态方法不能隐藏一个实例方法。例如,下面的程序有两个编译器错误。
/* Java program to show that if static methods are redefined by
a derived class, then it is not overriding but hidding. */
// Superclass
class Base {
// Static method in base class which will be hidden in subclass
public static void display() {
System.out.println("Static or class method from Base");
}
// Non-static method which will be overridden in derived class
public void print() {
System.out.println("Non-static or Instance method from Base");
}
}
// Subclass
class Derived extends Base {
// Static is removed here (Causes Compiler Error)
public void display() {
System.out.println("Non-static method from Derived");
}
// Static is added here (Causes Compiler Error)
public static void print() {
System.out.println("Static method from Derived");
}
}
4) 在一个子类(或派生类)中,我们可以重载从超类继承的方法。这种重载方法既不隐藏也不覆盖超类的方法,它们是新的方法,对子类来说是独一无二的。
参考文献:
http://docs.oracle.com/javase/tutorial/java/IandI/override.html