Вопрос по oop, .net, c# – Как перегрузка - это время компиляции, а переопределение - время выполнения?

17

Folks

Я наткнулся на множество тем для понимания полиморфизма (как времени компиляции, так и времени выполнения). Я был удивлен, увидев некоторые ссылки, где программисты заявляют, что перегрузка - это время выполнения, а переопределение - время компиляции.

Что я хочу знать здесь:

Runtime Polymorphism with a REAL TIME example and small code and what scenario we should use. Compile time Polymorphism with REAL TIME example and small code and when to use.

Потому что я прочитал много теоретических определений, но меня это не устраивает.

Кроме того, я подумал, что, где я также чувствовал, перегрузка должна быть во время выполнения, потому что, скажем, у меня есть метод, который вычисляет Площадь, только во время выполнения он решает, какой перегруженный метод вызывать на основе параметров, которые я передаю (скажем, если я передаю только один параметр, он должен запускать Square, а если параметры 2, он должен запускать Rectangle) .... Так разве я не могу требовать его выполнения? Как его время выполнения? (Большинство говорят, теоретически, перегрузка - это время компиляции, но они даже не дают правильный пример реального времени ... очень немногие утверждают, что время выполнения) ....

Кроме того, я считаю, что переопределение - это время компиляции, потому что, пока вы пишете код и выполняете компиляцию, вы гарантируете, что используете виртуальное ключевое слово, а также переопределяете этот метод в производном классе, что в противном случае могло бы привести к ошибке времени компиляции. Так что я чувствую время компиляции, так же, как я видел в потоке ..... Но большинство потоков требует его выполнения: D

Я в замешательстве :( Этот вопрос является дополнительным к моим вопросам 1 и 2. Пожалуйста, помогите с примером в реальном времени .., поскольку я уже знаком с теоретическими определениями .... :(

Спасибо....

Хммм Джефф, но это все о чем? Learner
Если я вообще понимаю ваш вопрос: время выполнения, вызов виртуальных методов. время компиляции, вызывая любой другой метод. Jeff Mercado

Ваш Ответ

3   ответа
16

олиморфизм, потому что компилятор точно знает, какой метод вы вызываете. Например:

public static class test
{
    static void Main(string[] args)
    {
        Foo();
        Foo("test");
    }

    public static void Foo()
    {
        Console.WriteLine("No message supplied");
    }

    public static void Foo(string message)
    {
        Console.WriteLine(message);
    }
}

В этом случае компилятор точно знает, какой метод Foo () мы вызываем, основываясь на количестве / типе параметров.

Переопределение является примером динамического (динамического) полиморфизма). Это связано с тем фактом, что компилятор не обязательно знает, какой тип объекта передается во время компиляции. Предположим, у вас есть следующие классы в библиотеке:

public static class MessagePrinter
{
    public static void PrintMessage(IMessage message)
    {
        Console.WriteLine(message.GetMessage());
    }
}

public interface IMessage
{
    public string GetMessage();
}

public class XMLMessage : IMessage
{
    public string GetMessage()
    {
        return "This is an XML Message";
    }
}

public class SOAPMessage : IMessage
{
    public string GetMessage()
    {
        return "This is a SOAP Message";
    }
}

Во время компиляции вы не знаете, передает ли вызывающая сторона этой функции XMLMessage, SOAPMessage или, возможно, другой тип IMessage, определенный в другом месте. Когда функция PrintMessage () вызывается, она определяет, какую версию GetMessage () использовать во время выполнения, в зависимости от типа передаваемого IMessage.

In the case of Overloading, the compiler is aware of exactly which method you are calling. Правда, если вы не используетеdynamic ключевое слово. в этом случае разрешение перегрузки выполняется во время выполнения.
просто отвлечься от проблемы'Foo': cannot declare instance members in a static classВаш метод должен быть статическим.
Если вы используетеdynamic ключевое слово, не имеет значения, перегрузили ли вы свой метод или нет; все разрешение метода выполняется во время выполнения.
Мне потребовалась минута, чтобы понять, что вы имели в виду, но я вижу, что вы имеете в виду ваши изменения. Спасибо за указание на то, что в первом примере я объявлял члены экземпляра в статическом классе. Я поспешно скомбинировал этот пример и не заметил.
Джон, я должен работать с такими людьми, как ты, по двум причинам. 1. Обучение материалам в режиме реального времени и удовлетворительно и для страсти, а не программирование ради выполнения задачи и получения оплаты. 2. Ваше отношение к тому, чтобы поделиться своими знаниями и, что наиболее важно, таким образом, чтобы это могло прийти в голову людям, которые задают вопрос ... В отличие от MSDN ...: (... Хорошо, большое спасибо, Джон, твой пример заставил меня понять это большая степень концепции .... Happy :) ура Learner
3

Полиморфизм (Руководство по программированию в C #)

Подобный ответ:Время компиляции и время выполнения Полиморфизм

Ну, есть два типа полиморфизма, как указано ниже:

Static Polymorphism (Early binding) Dynamic Polymorphism (Late binding)

Static Polymorphism(Early Binding):

Статический полиморфизм также известен как раннее связывание и полиморфизм времени компиляции. Перегрузка методов и перегрузка операторов являются примерами одного и того же.

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

Например:

public class Test
{
    public Test()
    {

    }

    public int add(int no1, int no2)
    {

    }

    public int add(int no1, int no2, int no3)

    {

    }
}

class Program
{
    static void Main(string[] args)
    {
        Test tst = new Test();
        int sum = tst.add(10, 20);

        // here in above statement compiler is aware at compile time that need to call function add(int no1, int no2), hence it is called early binding and it is fixed so called static binding.
    }
}

Dynamic Polymorphism(Late Binding):

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal sound");
    }
}

public class Dog:Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Dog sound");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Animal an = new Dog();
        an.MakeSound();           
        Console.ReadLine();
    }
}

Как и в приведенном выше коде, как и любой другой вызов виртуального метода, будет скомпилирована инструкция IL callvirt. Это означает, что фактический вызываемый метод определяется во время выполнения (если JIT не может оптимизировать какой-то особый случай), но компилятор проверил, что метод существует, он выбрал наиболее подходящую перегрузку (если есть) и имеет гарантию что указатель на функцию будет существовать в четко определенном месте в vtable типа (даже если это детали реализации). Процесс разрешения виртуального вызова чрезвычайно быстр (вам нужно только разыменовать несколько указателей), поэтому он не имеет большого значения.

@Divine - время компиляции, потому что компилятор знает, что он должен вызывать какой метод, например, если там есть 2 параметра, компилятор легко обнаруживает, что он должен вызывать только метод 2 параметров ... если 3, чем вызов gose для параметра 3 ...
@ Divine-компилятор знает о сигнатуре методов класса, и это может быть легко решено ...
Пранай спасибо. Но почему только когда я ввожу значение во время выполнения, скажем, только 2 параметра в вашем случае, он решает вызвать метод с 2 параметрами? Он просто компилируется во время компиляции ... как вы можете назвать его как время компиляции :( Это время выполнения, потому что во время выполнения только на основе входных данных он запускает соответствующую функцию .... Learner
0
public class Animal {
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal sound");
    } }

public class Dog:Animal {
    public override void MakeSound()
    {
        Console.WriteLine("Dog sound");
    } }

class Program {
    static void Main(string[] args)
    {
        Animal an = new Dog();
        an.MakeSound();           
        Console.ReadLine();
    } }

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

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