Страница 102 из 502
В C# определено понятие сигнатуры, обозначающее имя метода и список его параметров; Применительно к перегрузке это понятие означает, что в одном классе не должно существовать двух методов с одной и той же сигнатурой. Следует подчеркнуть, что в сигнатуру не входит тип возвращаемого значения, поскольку он не учитывается, когда компилятор C# принимает решение о перегрузке метода. В сигнатуру не входит также модификатор params.
Перегрузка конструкторов
Как и методы, конструкторы также могут перегружаться. Это дает возможность конструировать объекты самыми разными способами. В качестве примера рассмотрим следующую программу.
<b>// Продемонстрировать перегрузку конструктора.</b>
<b>using System;</b>
<b>class MyClass { </b>
<b> public int x;</b>
<b> public MyClass() {</b>
<b> Console.WriteLine("В конструкторе MyClass()."); x = 0;</b>
<b> }</b>
<b> public MyClass(int i) {</b>
<b> Console.WriteLine("В конструкторе MyClass(int)."); x = i ;</b>
<b> }</b>
<b> public MyClass(double d) {</b>
<b> Console.WriteLine("В конструкторе MyClass(double)."); x = (int) d;</b>
<b> }</b>
<b> public MyClass(int i, int j) {</b>
<b> Console.WriteLine("В конструкторе MyClass(int, int)."); x = i * j;</b>
<b> }</b>
<b>}</b>
<b>class OverloadConsDemo { </b>
<b> static void Main() {</b>
<b> MyClass t1 = new MyClass();</b>
<b> MyClass t2 = new MyClass(88);</b>
<b> MyClass t3 = new MyClass(17.23);</b>
<b> MyClass t4 = new MyClass(2, 4);</b>
<b> Console.WriteLine("t1.x: " + t1.x);</b>
<b> Console.WriteLine("t2.х: " + t2.x);</b>
<b> Console.WriteLine("t3.x: " + t3.x);</b>
<b> Console.WriteLine("t4.x: " + t4.x);</b>
<b> }</b>
<b>}</b>
При выполнении этой программы получается следующий результат.
<b>В конструкторе MyClass().</b>
<b>В конструкторе MyClass (int) .</b>
<b>В конструкторе MyClass(double).</b>
<b>В конструкторе MyClass (int, int). </b>
<b>t1.x: 0 </b>
<b>t2.x: 88 </b>
<b>t3.x: 17 </b>
<b>t4.x: 8</b>
В данном примере конструктор MyClass() перегружается четыре раза, всякий раз конструируя объект по-разному. Подходящий конструктор вызывается каждый раз, исходя из аргументов, указываемых при выполнении оператора new. Перегрузка конструктора класса предоставляет пользователю этого класса дополнительные преимущества в конструировании объектов.
Одна из самых распространенных причин для перегрузки конструкторов заключается в необходимости предоставить возможность одним объектам инициализировать другие. В качестве примера ниже приведен усовершенствованный вариант разработанного ранее класса Stack, позволяющий конструировать один стек из другого.
<b>// Класс для хранения символов в стеке.</b>
<b>using System;</b>
<b>class Stack {</b>
<b> // Эти члены класса являются закрытыми, </b>
<b> char[] stck; // массив, содержащий стек </b>
<b> int tos; // индекс вершины стека</b>
<b> // Сконструировать пустой объект класса Stack по заданному размеру стека, </b>
<b> public Stack(int size) {</b>
<b> stck = new char[size]; // распределить память для стека </b>
<b> tos = 0;</b>
<b> }</b>
<b> // Сконструировать объект класса Stack из существующего стека, </b>
<b> public Stack(Stack ob) {</b>
<b> // Распределить память для стека, </b>
<b> stck = new char[ob.stck.Length];</b>
<b> // Скопировать элементы в новый стек, </b>
<b> for (int i=0; i < ob.tos; i++) </b>
<b> stck[i] = ob.stck[i];</b>
<b> // Установить переменную tos для нового стека, </b>
<b> tos = ob.tos;</b>
<b> }</b>
<b> // Поместить символы в стек, </b>
<b> public void Push(char ch) { </b>
<b> if(tos==stck.Length) {</b>