Пример доступа к методам и свойствам унаследованных классов с помощью ссылки на базовый класс
В примере изучается:
- способы доступа к экземплярам унаследованных классов с помощью ссылки на базовый класс;
- изучение особенностей использования ключевых слов is, as;
- способы вызова одноименных методов в иерархии классов.
Содержание
Поиск на других ресурсах:
Условие задачи
Объявить класс Figure, который содержит поле name определяющее название фигуры. В классе Figure объявить следующие методы:
- конструктор с 1 параметром;
- метод Display() для отображения названия фигуры.
Из класса Figure унаследовать класс Rectangle (прямоугольник) со следующими полями:
- координата левого верхнего угла (x1; y1);
- координата правого нижнего угла (x2; y2).
В классе Rectangle реализовать следующие методы и функции:
- конструктор с 5 параметрами, вызовающий конструктор базового класса Figure;
- конструктор без параметров, реализующий установку координат углов (0; 0), (1; 1) и вызывающий конструктор с 5 параметрами с помощью средства this;
- метод Display(), отображающий название фигуры и значение внутренних полей. Данный метод обращается к одноименному методу базового класса;
- метод Area(), возвращающий площадь прямоугольника.
Из класса Rectangle нужно унаследовать класс RectangleColor. В классе RectangleColor реализовать поле color (цвет) и следующие методы;
- конструктор с 6 параметрами, который вызывает конструктор базового класса Rectangle;
- конструктор без параметров, который устанавливает координаты (0; 0), (1; 1) и вызывает конструктор с 6 параметрами с помощью средства this;
- метод Display(), отображающий название фигуры и значения внутренних полей. Данный метод обращается к одноименному методу базового класса;
- метод Area(), возвращающий площадь прямоугольника. В методе вызывается метод Area() базового класса.
В функции Main() выполнить следующие действия:
- объявить ссылку на базовый класс Figure;
- создать экземпляры классов Rectangle и RectangleColor;
- продемонстрировать доступ к методам производных классов с помощью ссылки на класс Figure.
⇑
Выполнение. Текст программы
Ниже приведено решение задачи. Программа реализована как приложение Console Application.
using System; using static System.Console; namespace ConsoleApp1 { // Класс Figure class Figure { // Защищенное поле класса protected string name; // Конструктор с 1 параметром public Figure(string name) { this.name = name; } // Метод Display() public void Display() { WriteLine("Figure.name = {0}", name); } } // Класс Rectangle - наследует (расширяет) возможности класса Figure class Rectangle : Figure { // Скрытые поля - координаты точек protected double x1, y1, x2, y2; // Конструктор с 5 параметрами public Rectangle(string name, double x1, double y1, double x2, double y2) : base(name) // вызвать конструктор базового класса { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } // Конструктор без параметров, вызывает конструктор с 5 параметрами public Rectangle() : this("Rectangle", 0, 0, 1, 1) { } // Метод Display() - выводит значения полей, // вызывает одноименный метод базового класса. // Данный метод переопределяет метод Diplay() базового // класса Figure, поэтому указывается ключевое слово new public new void Display() { base.Display(); // вызвать метод Display базового класса Write("Rectangle: x1 = {0:f2}, y1 = {1:f2}, ", x1, y2); WriteLine("x2 = {0:f2}, y2 = {1:f2}", x2, y2); } // Метод возвращающий площадь прямоугольника public double Area() { return Math.Abs(x1 - x2) * Math.Abs(y1 - y2); } } // Класс RectangleColor - добавляет к прямоугольнику цвет, // наследует возможности класса Rectangle class RectangleColor : Rectangle { // Скрытое поле класса protected int color = 0; // Конструктор с 6 параметрами, // вызывает конструктор базового класса Rectangle public RectangleColor(string name, double x1, double x2, double y1, double y2, int color) : base(name, x1, y1, x2, y2) { this.color = color; } // Конструктор без параметров, // вызывает конструктор с 6 параметрами public RectangleColor() : this("RectangleColor", 0, 0, 1, 1, 0) { } // Метод Display() - вызывает одноименный метод базового класса, // чтоб его не спрятать, нужно использовать ключевое слово new public new void Display() { base.Display(); WriteLine("RectangleColor.color = {0}", color); } // Метод вычисления площади public new double Area() { return base.Area(); // вызов метода Area() базового класса } } class Program { static void Main(string[] args) { // 1. Объявить ссылку на базовый класс Figure refFg; // 2. Создать экземпляры классов Figure, Rectangle, Rectangle Figure objFg = new Figure("Figure"); Rectangle objRect = new Rectangle("Rectangle", 1, 2, 5, -4); RectangleColor objRectCol = new RectangleColor("RectangleColor", 1, 8, -1, 3, 2); // 3. Присвоить ссылке refFg значение ссылки objFg на базовый класс Figure refFg = objFg; refFg.Display(); // Вызывается метод Display() класса Figure WriteLine("-----------------------"); // 4. Присвоить ссылке refFg значение ссылки objRect refFg = objRect; // 4.1. Вызывается метод Display() класса Figure refFg.Display(); WriteLine("-----------------------"); // 4.2. Вызывается метод Display() класса Rectangle - способ 1 try { ((Rectangle)refFg).Display(); // явное приведение к типу Rectangle WriteLine("-----------------------"); } catch { // если приведение к типу произошло некорректно, то выход WriteLine("Error."); return; } // 4.3. Вызывается метод Display() класса Rectangle - способ 2. // В этом способе используется ключевое слово as, // реализующее попытку приведения одного типа к другому, // в нашем случае Figure => Rectangle Rectangle r = refFg as Rectangle; // объявить дополнительную ссылку типа Rectangle if (r != null) r.Display(); WriteLine("-----------------------"); // 4.4. Вызывается метод Display() класса Rectangle - способ 3. // Здесь используется ключевое слово is, которое позволяет // определить совместимость типов, результат проверки - тип bool. // Если типы можно привести, то возвращается true, иначе false. if (refFg is Rectangle) { (refFg as Rectangle).Display(); WriteLine("-----------------------"); } // 5. Объявить ссылку на экземпляр класса RectangleColor refFg = objRectCol; // 5.1. Вызвать метод Display() базового класса Figure (а не Rectangle) refFg.Display(); WriteLine("-----------------------"); // 5.2. Вызвать метод Display() класса Rectangle одним из способов, // описанных в пунктах 4.2 - 4.4. try { ((Rectangle)refFg).Display(); WriteLine("-----------------------"); } catch { WriteLine("Error."); return; } // 5.3. Вызвать метод Display() класса RectangleColor одним из способов, // описанных в пунктах 4.2 - 4.4. if (refFg is RectangleColor) { (refFg as RectangleColor).Display(); WriteLine("-----------------------"); } } } }
⇑
Связанные темы
- Наследование. Базовые понятия. Преимущества и недостатки. Общая форма. Простейшие примеры. Модификатор доступа protected
- Особенности применения ссылки на базовый класс. Ключевые слова as, is. Вызов методов с одинаковыми именами в ирерархиях наследования
⇑