Отличие mainClass cls = new childClass() от childClass cls = new childClass();

226
13 марта 2018, 00:13

Первый вопрос на стеке, прошу не пинать...

В C# недавно. Не могу понять отличие:

mainClass cls = new childClass();

от

childClass cls = new childClass();

mainClass абстрактный, childClass, как уже догадались, дочерний.
В нем переопределяю метод родительского класса getInfo()

Основной код программы:

class Program
{
    static void Main(string[] args)
    {
        mainClass _cls = new childClass();
        childClass cls = new childClass();
        cls.getInfo();
        Console.ReadKey();
    }
}

Код родительского класса:

abstract class mainClass
{
    public virtual void getInfo()
    {
        Console.WriteLine("In mainClass Method");
    }
}

Код дочернего классa:

class childClass : mainClass
{
    public override void getInfo()
    {
        Console.WriteLine("In childClass Method;");
    }
}
Answer 1

В вашем примере отличия лишь в типе переменной, но это (в вашем случае) не влияет на программу.

Все потому, что при вызове функции getInfo() языку важен не тип переменной, а реальный тип объекта (могу слегка напутать терминологию, но в c++ реальный тип называется динамическим. Можно ли использовать такое понятие с шарпом - не знаю). Так вот, перед вызовом getInfo() проверяется таблица виртуальных функций и вызывается нужный экземпляр.

А теперь в двух словах о том, когда есть разница.

Представьте, что у вас есть класс MovableObject и его подклассы - Human и Car. В MovableObject определён метод Move (с модификатором virtual), а в подклассах он переопределен (с модификатором override).

Тогда что так:

MovableObject obj = new Car();
obj.Move();

Что так:

Car car = new Car();
car.Move();

Разницы никакой. Однако код obj.GetWheels() не скомпилируется, в отоичие от car.GetWheels(), т.к. метод GetWheels определен лишь для типа Car.

И ещё одно: если бы вы не использовали в базовом классе virtual и в дочернем override, то произошёл бы так называемый name shadowing. И тогда код:

abstract class A {
     void Print() {
        Console.WriteLine("Base");
     }
}
class B : A {
    void Print() {
        Console.WriteLine("Derived");
    }
}
// где-то в коде
A obj1 = new B();
B obj2 = new B();
obj1.Print();
obj2.Print();

Вывел бы следующее:

Base
Derived

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

READ ALSO
Не суммируются значение с ячейки DataGridView в label

Не суммируются значение с ячейки DataGridView в label

Здравствуйте,пытаюсь передать выбранные данные с ячейки в label, при выборе множество ячеек из разных строк они не складываются,а лейблу просто...

162
comboBox не выводит знаечние

comboBox не выводит знаечние

есть две формы: в одной datagridview, во второй поля для заполнения таблицы из первой формыпроблема заключена в том, что значение в combobox вводятся,...

197
Обработка исключений. C#

Обработка исключений. C#

Зачем нам нужно ключевое слово finally в c# , если код после try/catch и так всегда выполняется?

176
Глюк при добавлении строк в БД Access - C#

Глюк при добавлении строк в БД Access - C#

ЗдравствуйтеИмеется БД Access из двух связанных таблиц

204