Можно ли не создавать этот конструктор по умолчанию?

public Kwadrat(double x)

: base(x)

{

Console.WriteLine("Работает конструктор класса квадрат с одним параметром");

}

Даже если параметр x классу Kwadrat не нужен, всё равно его нужно передать базовому классу. Базовый класс Rectangle перешлёт его дальше по иерархии классов, то есть в класс Figure, а в нём имеются все необходимые конструкторы, в том числе и с одним параметром.

//В Main():

Kwadrat Kw2 = new Kwadrat();

Kw2.Show();

//Выполнить!

Kwadrat Kw3 = new Kwadrat(17);

Kw3.Show();

//Выполнить!

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

Виртуальные методы и их переопределение

Так как в базовых классах описываются лишь наиболее общие характеристики объекта, то можно объявить какие-то общие методы. Например, для проекта Наследование такими методами могут быть аrea() и рerimetr(). В базовом классе неизвестна точная их реализация, поэтому их называют виртуальными.

Виртуальным называется метод, объявленный в базовом классе с помощью ключевого слова (virtual) и переопределяемый (override)в одном или в нескольких производных классов. Каждый производный класс может иметь свою собственную версию виртуального метода. Если вызывать на выполнение виртуальный метод через ссылку на базовый класс, то вызовется необходимая версия виртуального метода. Именно по типу объекта, на который указывает ссылка, и вызовется нужный виртуальный метод. Причем решение принимается динамически, во время выполнения программы. Если базовый класс содержит виртуальный метод и у него есть производные классы, то при наличии ссылки на различные типы объектов (посредством ссылки на базовый класс) будут выполняться различные версии виртуального метода.

Формат записи виртуального метода:

рublic virtual Тип_возврата Имя_метода(Список параметров)

{

//тело метода

}

Формат записи переопределяемого виртуального метода в производном классе:

рublic override Тип_возврата Имя_метода(Список параметров)

{

//тело метода

}

Переопределение виртуального метода в производном классе называют еще замещением метода.

Примечание 1:При переопределении метода сигнатуры (списки параметров) и типы возвращаемых значений у виртуального метода и у метода-заменителя должны совпадать.

Примечание 2:Виртуальный метод нельзя определять как статический, так как для вызова статического метода не нужно создавать ссылочную переменную; они вызываются по имени класса (например, Math.Sqrt(x)), но переопределенные виртуальные методы вызываются только через ссылки.

Примечание 3:В производных классов виртуальный метод переопределять не обязательно. В этом случае будет выполняться версия базового класса.

Примечание 4:Свойства класса можно так же разрабатывать со словом virtual, а затем переопределять их в производных классах.

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

Итак, сочетая наследование с возможностью переопределения (замещения) методов в базовом классе, можно определить общую форму методов, которые будут использованы производными классами.

Задание: В классе Figure создать виртуальные методы area() и perimetr(), и переопределить их во всех производных классах.

//В классе Figure:

public virtual double area()

{

return 0.0;

}

public virtual double perimetr()

{

return 0.0;

}

//В классе Rectangle:

public override double area()////площадь

{ return Width * Height; }

public override double perimetr()//периметр
{ return 2 * (Width + Height); }

Эти методы нужно изменить, добавив лишь слово override.

Наши рекомендации