8.1.2. Конструкторы классов и наследование
Как производный, так и базовый классы могут не иметь конструкторов, созданных программистом. В этом случае при создании объекта производного класса автоматически вызываются конструкторы, созданные компилятором по умолчанию. Именно так создавался объект obj в программе, код которой был приведен в листинге 8.3. Однако такой способ создания объектов является неприемлемым, если при создании объекта требуется выполнить инициализацию его полей некоторыми конкретными значениями. Для выполнения такой инициализации программистом должен быть определен конструктор с параметрами производного класса, так как конструкторы не наследуются.
В процессе создания объекта производного класса запускаются два конструктора: вначале конструктор базового класса создает ту часть объекта, которая определена в базовом классе, а затем конструктор производного класса инициализирует поля объекта, которые добавлены в производном классе. Такое разделений функций конструкторов имеет смысл, так как базовый класс не имеет доступа к полям своих производных классов, в результате объект создается по частям.
Базовый класс может иметь конструктор по умолчанию или созданный программистом. Рассмотрим оба варианта использования конструктора базового класса.
При использовании конструктора базового класса по умолчанию, он вызывается неявно. Добавим в код программы, приведенной в листинге 8.3 конструктор производного класса (листинг 8.4).
Листинг 8.4. Определение в производном классе конструктора с параметрами
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class A
{
int d; // закрытое поле базового класса
public int D
{
get // свойство чтения значения поля d
{ return d; }
set // свойство установки значения поля d
{ d=value; }
}
}
class B : A
{
int k; // закрытое поле производного класса
// конструктор производного класса
public B(int d1, int k)
{
// инициализация закрытого поля d в базовом классе путем обращения к
// методу-свойству D базового класса. В свойстве D вызывается метод set
D = d1;
// инициализация собственного закрытого поля k
this.k = k;
}
public void Print()
{
Console.WriteLine("значение унаследованного поля = {0}", D);
Console.WriteLine("значение собственного поля = {0}", k);
}
}
class Program
{
static void Main(string[] args)
{
B obj = new B(3,5);
obj.Print();
}
}
}
Эта программа выведет следующие строки:
Значение унаследованного поля = 3
Значение собственного поля =5
Если в базовом классе конструктор был определен, то требуется выполнить его явный вызов в конструкторе производного класса. В этом случае в заголовке определения конструктора производного класса следует использовать ключевое слово base для вызова конструктора базового класса:
имя_производного_класса (список параметров) : base (список параметров)
{
// тело конструктора
}
Список параметров конструктора производного класса должен состоять из параметров, необходимых для передачи конструктору базового класса и параметров, необходимых для инициализации собственных полей.
Изменим код программы, приведенной в листинге 8.4 так, чтобы в базовом и производном классах были определены конструкторы с параметрами (листинг 8.5).
Листинг 8.5. Определение в базовом и производном классах конструкторов с параметрами
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class A
{
int d;
public A(int d) // конструктор с параметрами базового класса
{
this.d = d;
}
public int D
{
get
{ return d; }
set
{ d=value; }
}
}
class B : A
{
int k;
public A(int d)
// конструктор с параметрами производного класса
// выполняет явный вызов конструктора базового класса
public B(int d, int k) : base(d)
{ this.k = k; }
public void Print()
{
Console.WriteLine("значение унаследованного поля = {0}", D);
Console.WriteLine("значение собственного поля = {0}", k);
}
}
class Program
{
static void Main(string[] args)
{
B obj = new B(3,5);
obj.Print();
}
}
}
Базовый класс может иметь несколько конструкторов, каждый из которых может быть вызван с помощью ключевого слова base. Если в конструкторе производного класса отсутствует служебное слово base, то автоматически вызывается конструктор базового класса, определенный по умолчанию.
Примечание. Ключевое слово base можно использовать в любой ситуации, когда из производного класса необходимо обратиться к открытым или защищенным членам базового класса: применение этого ключевого слова не ограничено конструктором.
- Лабораторная работа 6 Тема: Наследование классов
- Базовые и производные классы
- Доступ к наследуемым элементам
- 8.1.2. Конструкторы классов и наследование
- 8.2. Виртуальные методы. Динамическое связывание
- 8.3. Абстрактные классы
- 8.4. Класс System.Object
- Главные методы объекта System.Object
- Контрольные вопросы и задания
- Варианты заданий