C#. Пример доступа к методам и свойствам унаследованных классов с помощью ссылки на базовый класс




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

В примере изучается:

  • способы доступа к экземплярам унаследованных классов с помощью ссылки на базовый класс;
  • изучение особенностей использования ключевых слов 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("-----------------------");
      }
    }
  }
}

 


Связанные темы