Функциональная перегрузка переопределения в Java

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

10
задан Peter Mortensen 14 January 2010 в 00:13
поделиться

6 ответов

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

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

Например:

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.

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

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

SRC: http://www.jchq.net/tutorial/06_02tut.htm

10
ответ дан 3 December 2019 в 13:34
поделиться

Перегрузка:

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.

6
ответ дан 3 December 2019 в 13:34
поделиться

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

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
ответ дан 3 December 2019 в 13:34
поделиться

Посмотрите через галерею MatPlotlib , все графики там имеются свой исходный код. Найти тот, который вам нравится, вырезать и вставить, рассекать!

-121--4746540-

Переопределение

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

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;
  }
}
1
ответ дан 3 December 2019 в 13:34
поделиться

Об интересном моменте, о котором стоит упомянуть:

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 будет вызван, но это не так. Первый метод вызывается, поскольку правильный метод выбирается во время компиляции.

2
ответ дан 3 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: