Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций.pdf
Скачиваний:
41
Добавлен:
27.05.2015
Размер:
1.53 Mб
Скачать

return sum;

}

}

 

 

 

MyClass c = new MyClass();

 

int[] m = new int[4] {5,6,7,8};

 

int s1

= c.Sum(m);

// s1

= 26

int s2

= c.Sum(1, 2, 3); // s2

= 6

int s3

= c.Sum(1, 2.1, 3); // ошибка

У метода идентификаторы формальных параметров могут совпадать с идентификаторами полей класса, к которому принадлежит метод. В этом случае, внутри метода видимым является формальный параметр, а для доступа к полю класса может быть использовано ключевое слово this, например:

class MyClass

{

private int x;

public void SetX(int x)

{

this.x = x;

}

}

Ключевое слово this означает объект, который вызвал метод, поэтому оно может быть использовано в любом методе класса, например, далее в конструкторе.

3.6 Перегрузка методов

Язык C# допускает наличие в классе нескольких методов с одинаковым идентификатором. Такое описание называется перегрузкой методов. В этом случае все методы с одинаковым идентификатором должны отличаться количеством и/или типом параметров. Это требование необходимо для того, чтобы компилятор мог распознать необходимый для применения метод. Если ни один метод не подходит для заданного набора параметров, то программа не может быть скомпилирована.

Пример: класс, в котором определено вещественное поле и перегруженный метод, позволяющий выдавать значение этого поля в разных форматах.

class MyClass

{

public double d; public string GetD()

{

return d.ToString();

}

public string GetD(int n)

{

return String.Format("{0:F"+n.ToString()+"}",d);

}

51

public string GetD(int n, char c)

{

return String.Format("{0:"+c+n.ToString()+"}", d);

}

}

 

 

 

MyClass c = new MyClass();

 

 

c.d = 1234.567;

 

 

string s1

= c.GetD();

// s1

= "1234,567"

string s2

= c.GetD(2);

// s2

= "1234,57"

string s3

= c.GetD(2,'N');

// s3

= "1 234,57"

При перегрузке методов возможно изменение возвращаемого типа, но только с изменением типа и/или количества параметров.

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

class MyClass

{

public int Divide(int a, int b)

{

return a/b;

}

public double Divide(double a, double b)

{

return a/b;

}

}

 

 

 

 

 

MyClass c = new MyClass();

 

 

 

 

int i = c.Divide(7,2);

// i = 3

 

double d1

= c.Divide(7,2);

//

d1

=

3

double d2

= c.Divide(7,2.0);

//

d2

=

3.5

Перегруженные методы могут иметь одинаковое количество и тип параметров в случае, если в одной реализации метода часть параметров передается по ссылке (ref или out), а в другой – по значению.

public void Method(int a) {...}; public void Method(ref int a) {...};

Однако нельзя перегрузить метод, если в одной реализации передача осуществляется по ссылке out, а в другой – по ссылке ref.

public void Method(out int a) {...}; public void Method(ref int a) {...};

52

3.7 Конструкторы

Конструкторы представляют собой специальные методы, вызываемые при создании объекта. Каждый класс имеет конструктор по умолчанию1, не имеющий параметров и устанавливающий значения всех членов-данных в “нулевое” состояние (если не переопределен), а также может иметь произвольное количество конструкторов с разным набором параметров.

Основное назначение конструктора – инициализация членов-данных и подготовка объекта к работе.

Формальная схема конструктора имеет вид:

<доступ> <имя_класса>([<список параметров>])

{

<тело конструктора>

}

Чаще всего <доступ> имеет значение public, т.к. конструктор вызывается при создании объектов из-за пределов класса.

Вклассе может быть описано несколько конструкторов, т.е. конструкторы, как

илюбые методы, могут быть перегружены.

Пример: дополним класс Figure конструкторами с разными наборами параметров. Будем считать, что значения по умолчанию для полей posX, posY – 1, а для поля sType – “Не задан”. Инициализацию полей posX, posY, для примера, будем проводить только в конструкторах.

class Figure

{

private string sType="Не задан"; public int posX, posY;

public string GetSType()

{

return sType;

}

public void SetSType(string n_sType)

{

if (n_sType.Trim() != "") sType = n_sType.Trim();

}

public Figure Duplicate()

{

return new Figure(sType,posX,posY);

}

public Figure() // Переопределение конструктора по умолчанию

{

posX = posY = 1;

}

public Figure(string n_sType) // Конструктор с одним параметром

1 Конструктор по умолчанию скрывается, если определен хотя бы один другой конструктор.

53

{

SetType(n_sType); posX = posY = 1;

}

// Конструктор с тремя параметрами

public Figure(string n_sType, int n_posX, int n_posY)

{

SetType(n_sType); posX = n_posX; posY = n_posY;

}

}

//Вызов конструктора по умолчанию

Figure figure1 = new Figure();

//Вызов конструктора с одним параметром

Figure figure2 = new Figure("Квадрат");

//Вызов конструктора с тремя параметрами

Figure figure3 = new Figure("Круг",5,6);

//Ошибка: конструктора с одним целочисленным параметром нет

//Figure figure4 = new Figure(5);

Также в приведенном выше примере был изменен метод Duplicate, т.к. имея конструктор с параметрами можно легко создать объект с копией свойств.

Если у класса определено несколько конструкторов, то один из них может вызывать другой. Для этого используется конструкция вида:

<доступ> <имя_класса>([<список параметров1>]) : this([<список параметров2>])

{

<тело конструктора>

}

Здесь <список параметров1> определяет набор формальных параметров текущего конструктора, а <список параметров2> – набор фактических параметров вызываемого конструктора. При этом, в <список параметров2> могут использоваться параметры из <список параметров1>.

В некоторых случаях <тело конструктора> может оставаться пустым, т.к. все действия выполняются в другом вызываемом конструкторе.

Например, конструкторы без параметров и с одним параметром из приведенного выше примера могут быть описаны с использованием конструктора с тремя параметрами следующим образом:

public Figure() : this("Не задан",1,1)

{

}

public Figure(string n_sType) : this(n_sType,1,1)

{

}

54