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

Ответы_ТП

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

места описания класса некоторые из этих спецификато ров могут быть запрещены.

Таблица 1.1. Спецификаторы класса

Специфи

Описание

 

 

 

 

 

 

 

 

 

new

Используется

для

 

вложенных

 

классов. Задает новое описание

public

Доступ не ограничен

 

 

protected

Используется

для

 

вложенных

internal

Доступ

только

из

данной

protected

Доступ только из данного и

private

Используется

для

 

вложенных

abstract

Абстрактный класс.

Применяется

sealed

Бесплодный

класс.

Применяется

static

Статический

класс.

 

Введен в

 

 

 

 

 

 

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

Если достаточный для хранения объекта объем памяти выделить не удалось, операция new генерирует исключение OutOfMemoryException . Рекомендуется предусматривать обработку этого исключения в программах, работающих с объек тами большого объема

30. Параметры методов класса

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

1.Вычисляются выражения, стоящие на месте аргументов.

2.Выделяется память под параметры метода в соответствии с их типом.

3.Каждому из параметров сопоставляется соответствующий аргумент (аргументы как бы накладываются на параметры и замещают их).

4.Выполняется тело метода.

Если метод возвращает значение, оно передается в точку вызова; если метод имеет тип void, управление передается на оператор, следующий после вызова.

При этом проверяется соответствие типов аргументов и параметров и при необходимости выполняется их преобразование. При несоответствии типов выдается диагностическое сообщение.

Листинг 1.3

usingSystem;

namespaceConsoleApplication1

{

classClass1

{

staticintMax(inta, intb) // метод выбора максимального значения

{if ( а> b ) return а; else return b;}

static void Main()

{int a = 2, b = 4;

int x = Max( a, b ); //вызовметода Max

Console.WriteLine( x );

//результат: 4

short tl = 3, t2 = 4;

 

 

intу = Max( t1 , t2 ) ;//

вызовметода Max

Console.WriteLine(у );

//

результат: 4

int z = Max( a+tl, tl/2*b): // вызовметода Max

Console.WriteLine(z );

//

результат 5

}

}

}

В классе описан метод Мах, который выбирает наибольшее из двух переданных ему значений. Параметры описаны как а и b. В методе Main выполняются три вызова Мах. В результате первого вызова методу Мах передаются два аргумента того же типа, что и параметры, во втором вызове — аргументы совместимого типа, в третьем - выражения.

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

Количество аргументов должно соответствовать количеству параметров. На имена никаких ограничений не накладывается: имена аргументов могут, как совпадать, так и не совпадать с именами параметров.

Существуют два способа передачи параметров: по значению и по ссылке.

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

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

2

В С# для обмена данными между вызывающей и вызываемой функциями предусмотрено четыре тина параметров:

параметры-значения;

параметры-ссылки — описываются с помощью ключевого слова ref;

выходные параметры — описываются с помощью ключевого слова out:

параметры-массивы — описываются с помощью ключевого слова params.

Ключевое слово предшествует описанию типа параметра. Если оно опущено, параметр считается параметром-значением. Параметр-массив может быть только один и должен располагаться последним в списке, например:

public int Calculate( int a, ref int b, out int c, params int[] d ) …

4.1.1.1 Параметры-значения

Параметр-значение описывается в заголовке метода следующим образом:

тип имя

Пример заголовка метода, имеющего один параметр-значение целого типа:

void P( int х )

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

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

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

3.1.1.2 Параметры-ссылки

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

требуется изменить значение каких-либо передаваемых в него величин. В этих случаях используются параметры-ссылки.

Признаком параметра-ссылки является ключевое слово refпередописанием параметра:

ref тип имя

Пример заголовка метода, имеющего один параметр-ссылку целого типа: voidF( refinty)

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

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

Проиллюстрируем передачу параметров-значений и параметров-ссылок на примере (листинг 1.4).

Листинг 1.4. Параметры-значения и параметры-ссылки

using System;

namespace ConsoleApplication1

{ class Class1

{static void P( int a, ref int b )

{a = 44; b = 33;

Console.WriteLine( "внутриметода {0} {1}”, a, b);

}

static void Main()

{

int a = 2, b = 4;

Console.WriteLine("довызова {0} {1}”, a, b );

P( a, ret b );

Console.WriteLine("послевызова {0} {1}", a, b );

}

}

}

3.1.1.3 Выходные параметры

Довольно часто возникает необходимость в методах, которые формируют несколько величин, например, если в методе создаются объекты или инициализи руются ресурсы. В этом случае становится неудобным ограничение параметров-ссылок: необходимость присваивания значения аргументу до вызов а метода. Это ограничение снимает спецификатор out. Параметру, имеющему этот специфика тор, должно быть обязательно присвоено значение внутри метода, компилятор за этим следит. Зато в вызывающем коде можно ограничиться описанием пере менной без инициализации.

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

ВС# два или больше методов внутри одного класса могут иметь одинаковое имя, но при условии, что их параметры будут различными. Такую ситуацию называют перегрузкой методов (methodoverloading), а методы, которые в ней задействованы, — перегруженными (overlo aded). Перегрузка методов — один из способов реализации полиморфизма в

С#.

Вобщем случае для создания перегрузки некоторого метода

достаточно объявить ещѐ одну его версию. Однако все перегруженные методы должны иметь списки параметров, которые отличаются по типу и/или количеству. Методам для перегрузки недостаточно отличаться лишь типами возвращаемых значений. Они должны отличаться типами или числом параметров. Конечно, перегруженные методы могут отличаться и типами возвращаемых значений. При вызове перегр уженного метода выполняется та его версия, параметры которой совпадают (по типу и количеству) с заданными аргументами.

using System;

class Overload {

public void ovlDemo() {

Console.W riteLine("Без параметров");

}

// Перегружаем метод ovlDemo() для одного

// целочисленного параметра,

publicvoidovlDemo(inta) {

Console.W riteLine(" Одинпараметр: " + a);

}

//Перегружаем метод ovlDemo() для двух

//целочисленных параметров,

public int ovlDemo(int a, int b) {

Console.W riteLine(" Два int-параметра: " + a + " " + b);

returna + b;

}

//Перегружаем метод ovlDemo() для двух

//double-параметров.

public double ovlDemo(double a, double b) { Console.W riteLine(" Два double-параметра: " + a + " "+ b ) ;

return a + b;

}

}

classOverloadDemo { public static void Main() {

Overload ob = new Overload(); int resl;

double resD;

// Вызываем все версии метода ovlDemo(). ob.ovlDemo();

Console.W riteLine(); ob.ovlDemo(2); Console.W riteLine();

resl = ob.ovlDemo(4, 6);

Console.W riteLine(" Результатвызова ob.ovlDemo(4, 6):”

+ resl);

Console.W riteLine();

resD = ob.ovlDemo(1.1, 2.32);

Console.W riteLine(" Результатвызова ob.ovlDemo(1.1, 2.2):”+resD);

}}

Посредством перегрузки методов в С# поддерживается

полиморфизм, поскольку это единственный способ реализации в С# парадигмы "один интерфейс — множество методов".

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

using System;

class MyClass {

public int x;

public MyClass() {

Console.W riteLine(" Внутриконструктора MyClass().");

x = 0;

}

publicMyClass(int i) {

Console.W riteLine(" Внутриконструктора MyClass(int).");

x = i ;

}

public MyClass(double d) {

Console.W riteLine(

"Внутриконструктора MyClass(double)."); x = (int) d;

}

public MyClass(inti, int j) { Console.W riteLine(

"ВнутриконструктораMyClass(int, int)."); x = i * j ;

}}

class OverloadConsDemo {

public static void Main() {

MyClass tl = new MyClass ();

MyClass t2 = new MyClass(88);

MyClass t3 = new MyClass(17.23);

MyClass t4 = new MyClass(2, 4);

Console.W riteLine("tl.x: " + tl.x);

Console.W riteLine("t2.x: " + t2.x);

Console.W riteLine("t3.x: " + t3.x);

Console.W riteLine("t4.x: " + t4.x);

}}

Конструктор MyClass () перегружен четырежды, и все конструкторы создают объекты по -разному. В зависимости от того, какие параметры заданы при выполнении оператора new, вызывается соответствующий конструктор. Перегружая конструктор класса, вы тем самым предоставляете пользова телю этого класса определенную гибкость в выборе способа создания объектов.

32. Перегрузка операторов отношений и преобразования

4.3.4Перегрузка операторов отношений

Операторы отношений (например, "==" или "<") также можно перегружать. Как правило, перегруженный оператор отношения возвращает одно из двух возможных значений: true или false. Это позволяет использовать перегруженные операторы отношений в условных выражениях.

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