Java中的函数覆盖 – 重载

覆盖和重载有什么区别?

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

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

例如:

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

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

  • 覆盖方法意味着它的整个function正在被替换。 覆盖是在子类中对父类中定义的方法执行的操作。

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

重载:

 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. 

如果没有定义第二个方法,它将inheritance第一个方法。 现在它将被A的子类中的第二个方法替换。

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

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

覆盖 – 您可以在inheritance方法体时重新定义方法体。

 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 */ } } 

有趣的是要提到:

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

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

覆盖

是否在子类中替换 (重写)由超类的子类inheritance的方法。

 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(); 

将运行fooB定义。 这不是那么直观,因为如果A类没有名为foo的方法,您将收到编译错误。 因此,对象的类型 A必须具有方法foo ,然后可以调用它,并且将执行实例的方法foo ,即B类的方法,因此是“执行时间”。

超载

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

 class A { void bar(int i) {} // The following method is overloading the method bar void bar(Object a) {} // The following will cause a compile error. // Parameters should differ for valid overload boolean bar(int i) { return true; } }