C#. Доступ до елементів базового класу з успадкованого класу. Ключові слова base, new. Приклади

Доступ до елементів базового класу з успадкованого класу. Ключові слова base, new. Приклади


Зміст


1. Ключове слово base. Призначення. У яких випадках використовується ключове слово base?

Ключове слово base є актуальним, якщо між класами використовується відношення спадковості. Тут можлива ситуація, коли в базовому і успадкованому класах існують методи (елементи) з однаковими іменами та сигнатурами. У цьому випадку елемент в похідному класі ховає відповідний елемент базового класу. Щоб з успадкованого класу доступитись до елементу базового класу потрібно використати ключове слово base.

Ключове слово base використовується в успадкованих класах у наступних випадках:

  • коли з конструктору похідного класу потрібно викликати конструктор базового класу. Більш детально про цей спосіб використання base описується тут;
  • коли з методу похідного класу потрібно викликати метод базового класу, якщо цей метод перевизначається;
  • коли з методу похідного класу потрібно отримати доступ до члена даних базового класу. У цьому випадку член даних має бути оголошений з будь-яким модифікатором доступу крім private;
  • коли з методу похідного класу потрібно отримати доступ до властивості базового класу (властивість не є оголошена як private);
  • коли потрібно підкреслити (конкретизувати), що в даному методі успадкованого класу використовуються елементи базового класу.

 

2. Виклик методів базового класу з допомогою base. Загальна форма. Приклад

З допомогою ключового слова base можна звертатись до будь-яких елементів базового класу, які не є прихованими (не містять модифікатора private).

Загальна форма використання ключового слова base для доступу до методу базового класу наступна:

base.Method();

де Method() – метод базового класу. Якщо у похідному класі немає реалізації методу з іменем Method(), то використання base необов’язкове.

Загальна форма використання ключового слова base для доступу до члена даних (не private члена даних)

base.variable;

де variable – ім’я члена даних базового класу.

 

3. Графічне пояснення доступу до елементів з допомогою ключового слова base

На рисунку 1 демонструється доступ до елементів базового класу A з методу похідного класу B.

C#. Спадковість. Ключове слово base. Способи доступу до різних елементів базового класу

Рисунок 1. Способи доступу до різних елементів класів A, B з методу MethodB()

 



4. Приклад, що демонструє використання ключового слова base для доступу до різних елементів базового класу

Нехай задано два класи A та B. Базовий клас A містить наступні елементи:

  • внутрішнє поле d з модифікатором доступу protected;
  • внутрішнє поле a з модифіктаором доступу private;
  • public-метод з іменем Method1();
  • public-властивість AA, яка реалізує доступ до внутрішнього поля a.

Клас B успадковує клас A і містить наступні елементи:

  • внутрішнє поле d з модифікатором доступу protected;
  • внутрішнє поле b з модифікатором доступу private;
  • public-метод з іменем Method1();
  • public-властивість BB, яка реалізувє доступ до внутрішнього поля b.

Демонстраційний текст програми, створеної за шаблоном Console Application наступний

using static System.Console;

namespace C_sharp
{
  // Клас A - базовий для класу B
  class A
  {
    // 1. Внутрішні поля класу
    protected int d;
    private int a;

    // 2. Конструктор класу
    public A()
    {
      // ініціалізує поля деякими значеннями
      a = 10;
      d = 20;
    }

    // 3. Загальнодоступний метод класу
    public void Method1()
    {
      WriteLine("A.Method1()");
    }

    // 4. Загальнодоступна властивість - доступ до поля a
    public int AA
    {
      get { return a; }
      set { a = value; }
    }
  }

  // Клас B - успадкований від класу A
  class B : A
  {
    // 1. Внутрішні поля класу
    // Поле d перекриває однойменне поле d класу A,
    protected int d;
    private int b;

    // 2. Конструктор класу
    public B()
    {
      d = 40;
      b = 50;
    }

    // 2. Метод, який перекриває метод Method1() класу A,
    // у цьому методі демонструється доступ
    // до різних елементів класу A
    public void Method1()
    {
      WriteLine("B.Method1()");

      // 1. Звертання до методу Method1() класу A
      base.Method1();

      // 2. Виклик властивості AA класу A
      int t = AA; // тут можна без слова base
      WriteLine("A.AA = {0}", t);

      // 3. Доступ до внутрішнього поля d класу A
      t = base.d; // field d of class A
      WriteLine("A.t = {0}", t);

      // 4. Доступ до поля a класу A - заборонено
      // t = base.a; // заборонено, поле A.a є private
    }

    // 3. Загально доступна властивість BB
    public int BB
    {
      get { return b; }
      set { b = value; }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Демонстрація використання ключового слова base
      // 1. Створити екземпляр класу B
      B objB = new B();

      // 2. Викликати метод Method1 класу B,
      // у цьому методі використовуються елементи класу A
      objB.Method1();
    }
  }
}

 

5. Доступ до властивостей базового класу з допомогою base. Приклад базового класу Circle та похідного класу Sector

У прикладі демонструється доступ до властивості базового класу. Задано два класи: Circle – базовий клас, Sector – успадкований клас від Circle. В обох класах є властивість Area. Щоб з похідного класу Sector викликати властивість Area базового класу потрібно звернутись наступним чином

base.Area;

Нижче наведено текст програми, що демонструє застосування ключового слова base.

using System;
using static System.Console;

namespace C_sharp
{
  // Клас Circle - коло
  class Circle
  {
    // 1. Внутрішні поля
    protected double radius; // радіус
    protected double x, y; // координати центру кола

    // 2. Конструктор
    public Circle(double _x, double _y, double _radius)
    {
      x = _x;
      y = _y;
      if (_radius <= 0)
        radius = 1.0;
      else
        radius = _radius;
    }

    // 3. Властивості - доступ до внутрішніх полів класу
    public double X
    {
      get { return x; }
      set { x = value; }
    }

    public double Y
    {
      get { return y; }
      set { y = value; }
    }

    public double Radius
    {
      get { return radius; }
      set
      {
        if (value <= 0)
          radius = 1.0;
        else
          radius = value;
      }
    }

    // 4. Властивість Area - повертає площу круга
    public double Area
    {
      get { return Math.PI * radius * radius; }
    }
  }

  // Клас Sector - сектор (частина кола)
  class Sector : Circle
  {
    // 1. Внутрішнє поле
    protected double alpha; // кут сектора alpha = 0..360

    // 2. Конструктор – викликає конструктор базового класу Circle
    public Sector(double _x, double _y, double _radius, double _alpha) :
                base(_x, _y, _radius)
    {
      if ((_alpha >= 0) && (_alpha < 360))
        alpha = _alpha;
      else
        alpha = 0.0;
    }

    // 3. Властивіть для доступу до внутрішнього поля
    public double Alpha
    {
      get { return alpha; }
      set
      {
        if ((value >= 0) && (value < 360))
          alpha = value;
        else
          alpha = 0.0;
      }
    }

    // 4. Властивість, яка обчислює площу сектора
    // викликає однойменну властивість базового класу
    public double Area
    {
      get
      {
        // Викликати властивість базового класу
        return base.Area * alpha / 360;
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      Sector sc = new Sector(1.5, 2.2, 3.0, 100);
      double x = sc.Area;

      // вивести площу сектора
      WriteLine("Area of sector = {0:f3}", x);
    }
  }
}

Як видно з вищенаведеного коду, у базовому класі Circle реалізовано властивість Area, яка використовується в однойменній властивості похідного класу Sector наступним чином

...

class Sector
{
  ...

  // 4. Властивість, яка обчислює площу сектора,
  // викликає однойменну властивість базового класу
  public double Area
  {
    get
    {
      // Викликати властивість базового класу
      return base.Area * alpha / 360;
    }
  }
}

...

 

6. Необхідність застосування ключового слова new

Ключове слово new може бути застосоване в успадкованому класі перед іменем елементу, який перекриває (ховає) ім’я базового класу. Використання слова new рекомендується компілятором у випадку, якщо потрібно підкреслити, що саме даний метод чи властивість перевизначають однойменний метод базового класу.
На рисунку 2 позначено використання слова new для перевизначення методу у похідному класі.

C#. Перевизначення методу базового класу. Ключове слово new

Рисунок 2. Способи реалізації методу Method(), який перевизначає однойменний метод базового класу

Якщо не вказувати ключове слово new в методі успадкованого класу, то це не вплине на функціональність програми. Однак, у цьому випадку компілятор буде видавати попередження на зразок:

B.Method hides inherited member A.Method. Use the new keywork if hiding was intended

Крім того, компілятор запропонує виправити цю неточність і, якщо потрібно, сам вставить ключове слово new в потрібному місці.

 


Зв’язані теми