Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5678 / 802 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 7:

Наследование и полиморфизм

< Лекция 6 || Лекция 7: 123456 || Лекция 8 >

Явное обращение к конструктору базового класса

Продолжаем совершенствовать наши классы A и B. Очередная задача – выяснить способы передачи управления конструктору базового класса при создании объекта — представителя производного класса.

Таким образом, передача управления конструктору базового класса осуществляется посредством конструкции

...(...):base(...){...},

которая располагается в объявлении конструктора класса-наследника между заголовком конструктора и телом. После ключевого слова base в скобках располагается список значений параметров конструктора базового класса. Очевидно, что выбор соответствующего конструктора определяется типом значений в списке (возможно, пустом) параметров:

using System;

/*private*/ class X
 {
 }

/*public*/ class A
{
public A(){val2_A = 0; val3_A = 0;}
// К этому конструктору также можно обратиться из производного класса. 
protected A(int key):this()
{val1_A = key;}
// А вот этот конструктор предназначен исключительно
// для внутреннего использования.
private A(int key1,int key2,int key3)
{val1_A = key1; val2_A = key2; val3_A = key3;}

public int val1_A = 0;
public void fun1_A (String str)
 {
Console.WriteLine("A's fun1_A:" + str);
this.fun2_A("private function from A:");	
fun3_A();
 }
private void fun2_A (String str)
{
Console.WriteLine(str + "A's fun2_A:" + val2_A.ToString());
}

protected int val3_A;
private void fun3_A ()
{
A a = new A(1,2,3);
a.fun2_A("Это наше внутреннее дело!");	
}	 
}

/*public*/ class B:A
{
// Явные обращения к конструкторам базового класса.
public B():base(){val1_B = 0;}
public B(int key):base(key){val1_B = key;}
}

class Class1
{
static void Main(string[] args)
{
B b0 = new B(125);
}
}
Листинг 7.1.

Для создания объектов в программе можно применять конструкторы следующих степеней защиты:

public – при создании объектов в рамках данного пространства имен, в методах любого класса — члена данного пространства имен;

protected – при создании объектов в рамках производного класса, в том числе при построении объектов производного класса, а также для внутреннего использования классом — владельцем данного конструктора;

private – применяется исключительно для внутреннего использования классом-владельцем данного конструктора.

Кто строит БАЗОВЫЙ ЭЛЕМЕНТ

Теперь (в рамках того же приложения) построим два новых класса:

class X
{
}
class Y:X
{
}

// Это уже в Main()
Y y = new Y();

Вся работа по созданию объекта – представителя класса Y при явном отсутствии конструкторов по умолчанию возлагается на КОНСТРУКТОРЫ УМОЛЧАНИЯ – те самые, которые самостоятельно строит транслятор.

Особых проблем не будет, если в производном классе явным образом начать объявлять конструкторы:

class X
{
}

class Y:X
{
public Y(int key){}
public Y(){} 
}

// Это уже в Main()
Y y0 = new Y();
Y y1 = new Y(125);

С этого момента в производном классе нет больше конструктора умолчания. Теперь все зависит от соответствия оператора определения объекта построенному нами конструктору.

Объявим в производном классе оба варианта конструкторов. И опять все хорошо. Конструктор умолчания базового класса (тот, который строится транслятором) продолжает исправно выполнять свою работу.

Проблемы в производном классе возникнут, если в базовом классе попытаться объявить вариант конструктора с параметрами:

class X
{
public X(int key){} 
}
class Y:X
{
public Y(int key){} // Нет конструктора умолчания базового класса!
public Y(){} // Нет конструктора умолчания базового класса!
}

// Это уже в Main()
Y y0 = new Y();
Y y1 = new Y(125);

И здесь транслятор начнет обижаться на конструкторы производного класса, требуя ЯВНОГО объявления конструктора базового класса БЕЗ параметров. Если вспомнить, что при ЛЮБОМ вмешательстве в дело построения конструкторов транслятор снимает с себя всю ответственность, причина негодования транслятора становится очевидной. Возможны два варианта решения проблемы:

  • явным образом заставить работать новый конструктор базового класса,
  • самостоятельно объявить новый вариант конструктора без параметров:
class X
{
public X(){}
public X(int key){} 
}
class Y:X
{
public Y(int key){} 
public Y():base(125){} 
}

// Это уже в Main()
Y y0 = new Y();
Y y1 = new Y(125);
< Лекция 6 || Лекция 7: 123456 || Лекция 8 >
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2