Java中的函数覆盖 - 重载

时间:2010-01-12 09:13:08

标签: java overloading override

覆盖和重载有什么区别?

6 个答案:

答案 0 :(得分:22)

  • 重载:根据指定参数的数量和类型在编译时选择方法签名

  • 覆盖:根据目标对象的实际类型(而不是表达式的编译时类型)在执行时选择方法实现

例如:

class Base
{
    void foo(int x)
    {
        System.out.println("Base.foo(int)");
    }

    void foo(double d)
    {
        System.out.println("Base.foo(double)");
    }
}

class Child extends Base
{
    @Override void foo (int x)
    {
        System.out.println("Child.foo(int)");
    }
}

...

Base b = new Child();
b.foo(10); // Prints Child.foo(int)
b.foo(5.0); // Prints Base.foo(double)

这两个调用都是重载的示例。有两种方法称为foo,编译器确定要调用的签名。

第一个电话是覆盖的示例。编译器选择签名“foo(int)”,但在执行时,目标对象的类型确定要使用的实现应该是Child中的实现。

答案 1 :(得分:10)

  • 重载方法是一种编译器技巧,允许您使用相同的名称根据参数执行不同的操作。

  • 覆盖方法意味着正在替换其整个功能。覆盖是在子类中为父类中定义的方法完成的。

src:http://www.jchq.net/tutorial/06_02Tut.htm

答案 2 :(得分:6)

重载:

public Bar foo(int some);
public Bar foo(int some, boolean x);  // Same method name, different signature.

覆盖:

public Bar foo(int some);   // Defined in some class A
public Bar foo(int some);   // Same method name and signature. Defined in subclass of A.

如果没有定义第二种方法,它将继承第一种方法。现在它将被A的子类中的第二个方法所取代。

答案 3 :(得分:4)

重载 - 类似签名 - 相同名称,不同参数

void foo() {
   /** overload */
}

void foo( int a ) {
   /** overload */
}

int foo() {
   /** this is NOT overloading, signature is for compiler SAME like void foo() */
}

覆盖 - 您可以在继承方法体时重新定义方法体。

class A {
   void foo() {
      /** definition A */
   }
}

class B extends A {
   void foo() {
      /** definition B, this definition will be used when you have instance of B */
   }
}

答案 4 :(得分:2)

有趣的是要提到:

public static doSomething(Collection<?> c) {
    // do something
}

public static doSomething(ArrayList<?> l) {
    // do something
}

public static void main(String[] args) {
    Collection<String> c = new ArrayList<String> ();
    doSomething(c); // which method get's called?
}

可以假设使用ArrayList参数的方法将被调用但不会。调用第一个方法,因为在编译时选择了正确的方法。

答案 5 :(得分:1)

覆盖

当超类中的子类继承的方法在子类中被替换(重写)时。

class A {
  void foo() {
    /** definition A of foo */
  }
}

class B extends A {
  void foo() {
    /** definition B of foo */
  }
}

现在,如果您使用以下方式致电foo

A a = new B();
a.foo();

B的{​​{1}}定义将会运行。这不是那么直观,因为如果类foo没有名为A的方法,您将收到编译错误。因此foo对象的{em>类型必须包含方法a,然后您可以调用它,方法A将执行实例的实例,这是类foo的实现,因此是“执行时间”。

过载

创建与现有方法同名的方法时。为避免编译时错误,您 以使用与现有参数不同的参数定义新方法。这样,方法将是可区分的。有一个具有相同名称和参数的方法,但不同的返回类型仍然是模糊的,因此会导致编译错误。重载示例:

foo