Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

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

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

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);

}

}

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

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);