Перегрузка переопределения функций в Java

В чем разница между переопределением и перегрузкой?

Ответ 1

  • Перегрузка: выбор метода подпись во время компиляции на основе количества и типа указанных аргументов

  • Переопределение: выбор метода во время выполнения на основе фактического типа целевого объекта (в отличие от типа выражения времени компиляции)

Например:

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.

Ответ 2

  • Перегрузка методов - это трюк компилятора, позволяющий использовать одно и то же имя для выполнения разных действий в зависимости от параметров.

  • Переопределение метода означает, что вся его функциональность заменяется. Переопределение - это что-то сделано в дочернем классе методу, определенному в родительском классе.

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

Ответ 3

Перегрузка:

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.

Ответ 4

Перегрузка - аналогичная подпись - то же имя, разные параметры

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

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

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

Override - вы можете переопределить тело метода, когда вы наследуете его.

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

Ответ 5

Интересно отметить:

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 called?
}

Можно предположить, что метод с аргументом ArrayList будет вызван, но это не так. Первый метод вызывается, так как правильный метод выбирается во время компиляции.

Ответ 6

Override

Это когда метод, который наследуется подклассом из суперкласса, заменяется (переопределяется) в подклассе.

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 foo. Это не так интуитивно, так как вы получите ошибку компиляции, если класс A не имел метода под названием foo. Таким образом, тип объекта A, который имеет значение 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;
  }
}