Принципы объектно-ориентированного программирования

         

Инициализаторы конструкторов



Инициализаторы конструкторов

Во всех конструкторах С#, кроме System.Object, конструкторы базового класса вызываются прямо перед исполнением первой строки конструктора. Эти инициализаторы конструкторов позволяют задавать класс и подлежащий вызову конструктор. Они бывают двух видов.

  • Инициализатор в виде base(...) активизирует конструктор базового класса текущего класса.
  • Инициализатор в виде this(...) позволяет текущему базовому классу вызвать другой конструктор, определенный в нем самом. Это полезно, когда вы перегрузили несколько конструкторов и хотите быть уверенными, что всегда будет вызван конструктор по умолчанию. О перегруженных методах см. главу 6, здесь же мы приведем их краткое и не совсем точное определение: перегруженными называются два и более методов с одинаковым именем, но с различными списками аргументов.


Чтобы увидеть порядок событий в действии, обратите внимание на следующий код: он сначала исполнит конструктор класса А, а затем конструктор класса В:

using System;

class A

<

public A() {

Console.WriteLine("A"); } }

class В : А

<

public B() {

Console.WriteLine("B"); } }

class DefaultlnitializerApp {

public static void MainQ

{

В b = new B();

} }

Этот код — функциональный эквивалент следующего, где производится явный вызов конструктора базового класса:

using System;

class A {

public A()

{

Console.WriteLine("A");

} }

class В : A /

{

public BO : baseO

{

Console.WriteLine("B");

} }

class BaseDefaultlnitializerApp <

public static void Main()

{

В b = new BO;

} }

А теперь рассмотрим более удачный пример ситуации, когда выгодно использовать инициализаторы конструкторов. У меня опять два класса: А и В. На этот раз у класса А два конструктора, один из них не требует аргументов, а другой принимает аргумент типа int. У класса В один конструктор, принимающий аргумент типа int. При создании класса В возникает проблема. Если запустить следующий код, будет вызван конструктор класса А, не принимающий аргументов:

using System;

class A <

public АО {

Console.WriteLine("A"); >

public A(int foo) {

Console.WriteLineC'A = {0}", foo); } }

class В : А {

public B(int foo) {

Console.WriteLineC'B = {0}", foo);

} }

class DerivedlnitializeMApp {

public static void MainQ

{

В Ь = new B(42);

} }

Как же гарантировать, что будет вызван именно нужный конструктор класса А1 Явно указав компилятору, какой конструктор в инициализаторе должен быть вызван первым, скажем, так:

using System;

class A {

public A()

{

Console. Writel_ine( "A");

}

public A(int foo) {

Console.WriteLineC'A = {0}", foo); } >

class В : А {

public B(int foo) ; base(foo)

{

Console.WriteLine("B = {0}". foo);

} >

class DerivedInitializer2App {

public static void Main()

< / В b = new B(42); /

} /

} /



Содержание раздела