Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ответы_ТП

.pdf
Скачиваний:
27
Добавлен:
21.05.2015
Размер:
880.4 Кб
Скачать

{ return this; }

public void Sety(double y)

{ this.y=y;}

}

21. Конструктор класса_ описание и назначение

Конструктор предназначен для инициализации объекта. Он вызывается авто матически при создании объекта класса с помощью операции new. Имя конст руктора совпадает с именем класса. Ниже перечислены свойства конструкторов:

Конструктор не возвращает значение, даже типа void.

Класс может иметь несколько конструкторов с разными параметрами для раз ных видов инициализации.

Если программист не указал ни одного конструктора или какие-то поля не были инициализированы, полям значимых типов присваивается нуль, полям ссылочных типов — значение null.

Конструктор, вызываемый без параметров, называется

конструктором по умолчанию.

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

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

доступ имя_класса{)

{

// тело конструктора

}

Обычно конструктор используется, чтобы придать переменным экземпляра, определенным в классе, начальные значения или выполнить исходные действия, необходимые для создания полностью сформированного объекта. Кроме того, обычно в качестве элемента доступ используется модификатор доступа public, поскольку конструкторы, как правило, вызываются вне их класса.

Все классы имеют конструкторы независимо от того, определите вы их или нет, поскольку С# автоматически предоставляет конструктор по умолчанию, который инициа лизирует все переменные -члены, имеющие тип значений, нулями, а переменные -члены ссылочного типа

null-значениями. Но если вы определите собственный конструктор, конструктор по умолчанию больше не используется.

Вот пример использования конструктора:

// Использование простого конструктора.

usingSystem;

classMyClass {

publicint x;

publicMyClass() {

x = 10;

}

}

c l a s sConsDemo {

p u b l i c s t a t i c void Main() {

MyClass t l = new MyClass();

MyClass t 2 = new MyClass();

Co n s o l e .W r i t e L i n e ( t l . x + " " + t 2 . x ) ;

}

}

Обратите внимание на public -определение конструктора, которое позволяет вызывать его из кода, определенного вне класса MyClass. Этот конструктор присваивает переменной экземпляра х значение 10. Конструктор MyClass () вызывает ся оператором new при создании объекта класса MyClass. Например, при выполнении строки MyClasstl = newMyClass();

для объектаtl вызывается конструктор MyClass (), который присваивает переменной экземплярраtl.x значение 10. То же самое справедливо и в отнош ении объекта t2, т.е. в результате создания объекта t2 значение переменной экземпляра t2.x также станет равным

10.

3.1.5.1 Параметризованные конструкторы

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

// Использование параметризованного конструктора.

using System;

classMyClass {

publicint x;

publicMyClass(inti) {

x = i;

}}

classParmConsDemo { public static void Main() {

MyClass t1 = new MyClass(10);

MyClass t2 = new MyClass(88);

Console.WriteLine (t1.x + " " + t2.x);

}

}

Результат выполнения этой программы выглядит так:

1088

Вконструкторе MyClass () этой версии программы определен один параметр с именем i, который используется для инициализации переменной экземпляра х. Таким образом, при выполнении строки кода

MyClasst1 = newMyClass(10);

параметру i передается значение 10, которое затем присваивается переменной экземпляра х.

22. Конструкторы и наследование

В иерархии классов как базовые, так и производные классы могут иметь собственные конструкторы. При этом возникает важный вопро с: какой конструктор отвечает за создание объекта производного класса? Конструктор базового класса создает часть объекта, соответствующую базовому классу, а конструктор производного класса — часть объекта, соответствующую производному классу.

Если конструктор определяется только в производном классе, процесс создания объекта несложен: просто создается объект производного класса. Часть объекта, соответствующая базовому классу, создается автоматически с помощью конструктора поумолчанию.

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

должны выполниться конструкторы обоих классов. В этом случае необходимо использовать еще одно ключевое слово С#base, которое имеет два назначения: вызвать конструктор базового класса и получить доступ к члену базового класса, который скрыт "за" членом производного класса.

Производный класс может вызывать конструктор, определенный в его базовом классе, используя расширенную форму объявления конструк тора производного класса и ключевое слово base. Формат расширенного объявления таков:

конструктор_производиого_класса(список_параметров) :

base (список_аргументов) {

// тело конструктора

}

Здесь с помощью элемента список_аргументов задаются аргументы, необходимые конструктору в базовом классе.

При задании производным классом bаsе-"метода" вызывается конструктор непосредственного базового класса. Таким образом, ключевое слово base всегда отсылает к базовому классу, стоящему в иерархии классов непосредств енно над вызывающим классом. Это справедливо и для многоуровневой иерархии. Чтобы передать аргументы конструктору базового класса, достаточно указать их в качестве аргументов " метода" base(). При отсутствии ключевого слова base автоматически вызывается конструктор базового класса , действующий по умолчанию .

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

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

23.Методы класса_ Назначение и описание

Метод — это функциональный элемент класса, который реализует вычисления или другие действия, выполняемые классом или экземпляром. Методы опреде ляют поведение класса.

>

Метод представляет собой законченный фрагмент кода, к котором можно обра титься по имени. Он описывается один раз, а вызываться может столько раз, сколько необходимо. Один и тот же метод может обрабатывать различные дан ные, переданные ему в качестве аргументов.

Синтаксис метода:

[ атрибуты ] [ спецификаторы ] тип имя_метода ( [ параметры ] ) тело метода

£

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

При описании методов можно использовать спецификаторы 1-7 из табл. 1.2, имеющие тот же смысл, что и для полей, а также спецификаторы virtual, sealed, override, abstract и extern, которые будут рассмотрены по мере необходимости. Чаше всего для методов задается спецификатор доступа public, ведь методы составля ют интерфейс класса - то, с чем работает пользователь, поэтому они должны быть доступны.

Статические (static) методы, или методы класса, можно вызывать, не создавая эк земпляр объекта. Именно таким образом используется

метод Main. Пример простейшего метода :

public doubleGety()// метод для получения поля у из листинга

{

return у;

}

Тип определяет, значение какого типа вычисляется с помощью метода. Часто употребляется термин «метод возвращает значение», поскольку после выполне ния метода происходит возврат в то место вызывающей функции, откуда был вызван метод, и передача туда значения выражения, записанного в операторе return. Если метод не возвращает никакого значения, в его заголовке задается тип void, а оператор return отсутствует.

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

Метод, не возвращающий значение, вызывается отдельным оператором, а метод, возвращающий значение, — в составе выражения в правой части оператора при сваивания.

Например, чтобы вычислить значение синуса для вещественной величины х, мы передаем ее в качестве аргумента в метод Sin кл асса Math, а чтобы вывести значение этой переменной на экран, мы передаем ее в метод W riteLine класса Console

double х = 0.1 ;

double у=Math .Sin(x):

Console.W riteLine(x);

При этом метод Sin возвращает в точку своего вызова вещественное значение си нуса, которое присваивается переменной у, а метод W riteLine ничего не возвращает.

Метод, не возвращающий значение, вызывается отдельным оператором, а метод, возвращающий значение, — в составе выражения в правой части оператора при сваивания.

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

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

public static double Sin( double a ):

Имя метода вкупе с количеством, типами и спецификаторами его параметров представляет собой сигнатуру мет ода — то, по чему один метод отличают от других. В классе не должно быть методов с одинаковыми сигнатурами.

В листинге 1.2 в класс Demo добавлены методы установки и получения значения поля у. Кроме того, статическое поле s закрыто, то есть определено по ум олчанию как private, а для его получения описан метод Gets, являющий собою пример статического метода.

Листинг 1.2. Простейшиеметоды

using System;

namespace ConsoleApplication1

{

class Demo

{

public int a=1;

public const double c=1.66; static string s=”Demo”; double y;

public double Get y()

{

return y;

}

public void Set y(double y_)

{

y=y_;

}

public static string Get s()

{

return s;

}

}

class Class1

{ static void Main()

{

Demo x=new Demo(); x.Set y(0.12);

Console.WriteLine(x.Gety());

Console.WriteLine(Demo.Gets());

// Console.WriteLine(Gets()); при вызове из другого метода этого объекта

}

}

}

Методы класса имеют непосредственный доступ к его закрытым полям. Метод, описанный со спецификатором static, должен обращаться только к статич еским полям класса. Обратите внимание на то, что статический метод вызывается через имя класса, а обычный через имя экземпляра.

При вызове метода из другого метода того же класса имя класса/экземпляра можно не указывать.

24. Многоадрессная передача

Одна из самых интересных возможностей делегата — поддержка

многоадресатной передачи (multicasting) . Многоадресатная передача

— это способность создавать список вызовов (или цепочку вызовов) методов, которые должны автоматически вызываться при вызове делегата. Такую цепочку создать нетрудно.

Достаточно создать экземпляр делегата, а затем для добавления методов в эту цепочку использовать оператор " +=". Для удаления метода из цепочки используется оператор" - = " . (Можно также для добавления и удаления методов использовать в отдельностиоператоры "+", " - " и "=", но чаще применяются составные операторы "+=" и "-=".)

Делегат с многоадресатной передачей имеет одно ограничение: он должен возвращать тип void.

Рассмотрим следующий пример многоадресатной передачи. Эт о — переработанный вариант предыдущих примеров, в котором тип string для значений, возвращаемых методами обработки строк, заменен типом void, а для возврата модифицированных строк используется ref-

параметр.

using System;

delegate void strMod(ref string st r); // Объявляем делегат.

classStringOps {

// Метод заменяет пробелы дефисами,

static void replaceSpaces(ref string a) {

Console.WriteLine("Замена пробелов дефисами.");

a = a.Replace(‘‘,’–‘ ) ;

}

static void removeSpaces(ref string a) {// Метод удаляет про белы.

string temp = "";

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]