Доступ к элементам базового класса из унаследованного класса. Ключевые слова base, new. Примеры
Содержание
- 1. Ключевое слово base. Назначение. В каких случаях используется ключевое слово base?
- 2. Вызов методов базового класса с помощью base. Общая форма. Пример
- 3. Графическое объяснение доступа к элементам с помощью ключевого слова base
- 4. Пример, который демонстрирует использования ключевого слова base для доступа к различным элементам базового класса
- 5. Доступ к свойствам базового класса с помощью base. Пример базового класса Circle и производного класса Sector
- 6. Необходимость применения ключевого слова 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.
Рисунок 1. Способы доступа к разным элементам классов A, B из метода Method()
⇑
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; // поле d класса 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 obj = 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 для переопределения метода в производном классе.
Рисунок 2. Способы реализации метода Method(), который переопределяет одноименный метод базового класса
Если не указывать ключевое слово new в методе унаследованного класса, то это не повлияет на функциональность программы. Однако, в этом случае компилятор будет выдавать предупреждение:
B.Method hides inherited member A.Method. Use the new keywork if hiding was intended
Кроме того, компилятор предложит исправить эту неточность и, если нужно, сам установит ключевое слово new в нужном месте.
⇑
Связанные темы
- Наследование. Базовые понятия. Преимущества и недостатки. Общая форма. Простейшие примеры. Модификатор доступа protected
- Использование конструкторов в классах при наследовании. Ключевое слово base при наследовании
⇑