Перегрузка и переопределение


105

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


2
@james: ты хотя бы пробовал гуглить ??
Mitch Wheat

Полагаю, ты этого не получишь.
Jon B

Джеймс: наверное, нет, и я чувствую себя довольно глупо, будучи не в состоянии объяснить простую концепцию

1
@james, думаю, вы интуитивно поняли эти концепции, не зная терминов. Я предполагаю, что вы самоучка. Вам, вероятно, следует взять книгу C # начального уровня не для изучения, а для закрепления того, что вы уже знаете. Это ошеломляет, но очень поможет на технических собеседованиях.
Майкл Медоуз

вы можете прочитать больше по этой ссылке: intquesans.blogspot.com/2011/05/…

Ответы:


220

Перегрузка

Перегрузка - это когда у вас есть несколько методов в одной области, с одним и тем же именем, но с разными сигнатурами.

//Overloading
public class test
{
    public void getStuff(int id)
    {}
    public void getStuff(string name)
    {}
}

Отмена

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

//Overriding
public class test
{
        public virtual void getStuff(int id)
        {
            //Get stuff default location
        }
}

public class test2 : test
{
        public override void getStuff(int id)
        {
            //base.getStuff(id);
            //or - Get stuff new location
        }
}

1
мне нравится этот ответ @cgreeno .. Спасибо
Ferrakkem Bhuiyan

1
@cgreeno я думаю , что вы пропустите voidдля getStuffвtest2
Махди

2
просто упомяну, что метод базового класса должен быть помечен как виртуальный, чтобы переопределить, иначе вы получите ошибку компиляции.
Алекс Стивенс

Эй, это может быть старое, но у меня все еще есть вопрос по этому поводу. Делает ли перегрузка доступной больше функциональности с помощью «одного» метода? Как я могу это сделать: getStuff(2, "Hello world!");или я могу это сделать getStuff("Myname", "Mysurname", "Hello World!");? Кто-нибудь может подтвердить, что это способ сделать это?
Sj03rs

Я думаю, что пример переопределения на самом деле является перезаписью, переопределение - это когда вы случайно переопределяете метод суперкласса или если вы хотите сделать это с помощью ключевого слова new в обоих случаях, переопределить или перезаписать, поведение отличается, когда вы объявляете Parent p = new Ребенок (); p.Method (); ... может я ошибаюсь и это просто еще один способ сделать почти то же самое. Может ли кто-нибудь объяснить это лучше меня?
Кристина Карраско,

35

Простые определения для перегрузки и переопределения

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

public class A
{
    public void print(int x, int y)
    {
        Console.WriteLine("Parent Method");
    }
}

public class B : A
{
    public void child()
    {
        Console.WriteLine("Child Method");
    }

    public void print(float x, float y)
    {
        Console.WriteLine("Overload child method");
    }
}

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

public class A
{
    public virtual void print()
    {
        Console.WriteLine("Parent Method");
    }
}

public class B : A
{
    public void child()
    {
        Console.WriteLine("Child Method");
    }

    public override void print()
    {
        Console.WriteLine("Overriding child method");
    }
}

Возможно, вы хотите добавить, что концепция переопределения применяется к отношениям родительский класс-подкласс.
Freakyuser

10

Я хочу поделиться примером, который имел для меня много смысла, когда я учился:

Это просто пример, который не включает виртуальный метод или базовый класс. Просто чтобы намекнуть на главную идею.

Допустим, есть машина для мойки автомобилей, у нее есть функция, называемая «Wash», и она принимает автомобиль в качестве типа.

Получает ввод автомобиля и моет машину.

public void Wash(Car anyCar){
       //wash the car
}

Давайте перегрузим функцию Wash ()

Перегрузка:

public void Wash(Truck anyTruck){
   //wash the Truck  
}

Раньше функция мойки была только для мытья автомобиля, но теперь она перегружена и для мытья грузовика.

  • Если предоставленный входной объект - автомобиль, он выполнит Wash (Car anyCar)
  • Если предоставленный входной объект - это Truck, то он выполнит Wash (Truck anyTruck).

Давайте переопределим функцию Wash ()

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

public override void Wash(Car anyCar){
   //check if the car has already cleaned
   if(anyCar.Clean){ 
       //wax the car
   }
   else{
       //wash the car
       //dry the car
       //wax the car
   }     
}

Функция стирки теперь имеет условие, позволяющее проверять, является ли автомобиль уже чистым и его не нужно мыть снова.

  • Если Автомобиль чистый, просто нанесите на него воск.

  • Если не чистая, то сначала вымойте машину, затем высушите, а затем воском.

.

Таким образом, функциональность была переопределена путем добавления новой функциональности или выполнения чего-то совершенно другого.


1
Это должен быть ответ. Проголосовал +
Джек

9
  • Перегрузка = несколько сигнатур методов, одно и то же имя метода
  • Переопределение = та же подпись метода (объявленная виртуальная), реализованная в подклассах

Проницательный интервьюер ответил бы:

В чем разница между перекрытием и затенением?


Никогда не знал, что это называется слежкой, хорошо знать. Единственная перегрузка и переопределение отношения - это перегрузка.
Самуэль

4

Как сказал Майкл:

  • Перегрузка = несколько сигнатур методов, одно и то же имя метода
  • Переопределение = та же подпись метода (объявленная виртуальная), реализованная в подклассах

и

  • Shadowing = Если рассматривается как DerivedClass, он использует производный метод, если как BaseClass он использует базовый метод.

3

Наличие более одного метода / конструктора с одинаковым именем, но разными параметрами называется перегрузкой. Это событие времени компиляции.

Class Addition 
{
   int add(int a, int b) 
   {
     return a+b;
   }
   int add(int a, int b, int c)
   {
     return a+b+c;
   }

   public static main (String[] args) 
   {
     Addition addNum = new Addition();
     System.out.println(addNum.add(1,2));
     System.out.println(addNum.add(1,2,3));
   }
}

O / p:

3
6

Переопределение - это событие времени выполнения, то есть в зависимости от вашего кода выходные данные меняются во время выполнения.

class Car
{
    public int topSpeed() 
    {
        return 200;
    }
}
class Ferrari extends Car
{
    public int topSpeed()
    {
        return 400;
    }
    public static void main(String args[])
    {
        Car car = new Ferrari();
        int num= car.topSpeed();
        System.out.println("Top speed for this car is: "+num);
    }
}

Обратите внимание, что в обоих классах topSpeed ​​() есть общий метод. Поскольку мы создали экземпляр Ferrari, мы получили другой результат.

O / p:

Top speed for this car is: 400

2

в C # нет Java, подобного скрытому переопределению, без переопределения ключевых слов в методе переопределения! см. эти реализации C #:

вариант 1 без переопределения : результат 200

    class Car {
        public int topSpeed() {
            return 200;
        }
    }

    class Ferrari : Car {
        public int topSpeed(){
                return 400;
        }
    }

    static void Main(string[] args){
        Car car = new Ferrari();
        int num= car.topSpeed();
        Console.WriteLine("Top speed for this car is: "+num);
        Console.ReadLine();
    }

вариант 2 с ключевым словом override : результат 400

    class Car {
        public virtual int topSpeed() {
            return 200;
        }
    }

    class Ferrari : Car {
        public override int topSpeed(){
                return 400;
        }
    }

    static void Main(string[] args){
        Car car = new Ferrari();
        int num= car.topSpeed();
        Console.WriteLine("Top speed for this car is: "+num);
        Console.ReadLine();
    }

ключевое слово virtual в классе Car противоположно final для Java, означает не final , вы можете переопределить или реализовать, если автомобиль был абстрактным


1

shadowing = поддерживает два определения в производном классе и, чтобы проецировать определение базового класса, затеняет (скрывает) определение производного класса и наоборот.


1

Еще один момент, который нужно добавить.

Перегрузка методов с одинаковым именем. Тот же или другой тип возвращаемого значения. Различное количество параметров или Другой тип параметров. В том же классе или производном классе.

int Add (int num1, int num2) int Add (int num1, int num2, int num3) double Add (int num1, int num2) double Add (double num1, double num2)

Может быть возможно в том же классе или производном классе. Обычно предпочитает принадлежать к тому же классу. Например, Console.WriteLine () имеет 19 перегруженных методов.

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

Можно рассматривать как полиморфизм времени компиляции (статическое / раннее связывание).

================================================== ================================================== знак равно

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

Имеет некоторые ограничения, например, переопределенный базовый метод должен быть виртуальным, абстрактным или переопределяемым. Вы не можете использовать модификаторы new, static или virtual для изменения метода переопределения.

Можно рассматривать как полиморфизм времени выполнения (динамическое / позднее связывание).

Помогает в управлении версиями http://msdn.microsoft.com/en-us/library/6fawty39.aspx

================================================== ================================================== знак равно

Полезные ссылки

http://msdn.microsoft.com/en-us/library/ms173152.aspx Полиморфизм времени компиляции и полиморфизм времени выполнения


Хорошая, с необходимыми деталями.
user3885927

1

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


Капитан здесь: Перегрузка метода дает вам несколько подписей разных методов с одним и тем же именем. Переопределение скрывает унаследованный член от классов или интерфейсов. улетает
SparK 04

1
@SparK Переопределение не скрывает участника. Вы можете либо переопределить или скрыть унаследованный элемент. Эти два варианта являются взаимоисключающими.
Servy 04

@Servy, неправильный подбор слов, я имел ввиду «заменители».
SparK 04

0

Перегрузка метода и переопределение метода - это две совершенно разные концепции. Перегрузка метода имеет то же имя метода, но с разными сигнатурами. Переопределение метода изменяет реализацию по умолчанию метода базового класса в производном классе. Ниже вы можете найти 2 отличных видеоурока, объясняющих эти концепции.

Переопределение метода против сокрытия

Перегрузка метода


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.