русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Использование классов


Дата добавления: 2015-01-08; просмотров: 1277; Нарушение авторских прав


Класс представляет собой создаваемый пользователем тип. Класс является ссылочным типом.

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

Поле – это переменная, объявленная в классе. У поля есть имя и тип. Метод – это функция, определенная в классе.

Рассмотрим определение класса, в котором содержатся два поля разных типов:

class Sportsmen

{

public string famile;

public int rez;

}

Здесь описан класс с именем Sportsmen с двумя полями: famile типа string и rez типа int. Описание класса располагается вне метода Main. В связи с этим уровень доступа к полям установлен максимальный (public – открытый доступ), что дает возможность доступа к полям из метода Main.

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

Sportsmen temp = new Sportsmen();

Далее в поля этой переменной можно поместить значения (инициализировать поля класса). Для доступа к полю экземпляра класса нужно указать имя переменной и после точки имя поля. Например,

using System;

class Sportsmen

{

public string famile;

public int rez;

}

class Program

{

static void Main(string[] args)

{

Sportsmen temp = new Sportsmen();

temp.famile = "Иванов";

temp.rez = 75;

Console.WriteLine(

"{0}\t{1:f2}", temp.famile, temp.rez);

Console.ReadKey();

}

}

или

Объявление массива классов. Например,

Sportsmen[] sp = new Sportsmen[5];

Здесь объявлен массив sp из 5 элементов, каждый из которых содержит 2 поля.



Далее для каждого элемента массива необходимо выделить память:

for (int i = 0; i < 5; i++) sp[i] = new Sportsmen();

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

Можно создать конструктор с параметрами для инициализации полей экземпляра класса:

using System;

class Sportsmen

{

public string famile;

public double rez;

public Sportsmen(string famile1, double rez1)

{

famile = famile1;

rez = rez1;

}

}

class Program

{

static void Main(string[] args)

{

Sportsmen[] sp = new Sportsmen[3] {

new Sportsmen("Иванов", 1.50),

new Sportsmen("Петров", 1.55),

new Sportsmen("Сидоров", 1.47)};

for (int i = 0; i < sp.Length; i++)

Console.WriteLine(

"Фам {0}\t Результат {1:f2}",

sp[i].famile, sp[i].rez);

}

}

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

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

using System;

class Sportsmen

{

public string famile;

public double rez;

}

class Sportsmen1 : Sportsmen

{

public string team;

}

class Program

{

static void Main(string[] args)

{

Sportsmen1 sp = new Sportsmen1();

sp.famile = "Иванов";

sp.rez = 77;

sp.team = "Спартак";

Console.WriteLine(

"Фам {0}\tКоманда {1}\tРезультат {2:f2}",

sp.famile, sp.team, sp.rez);

Console.ReadKey();

}

}

Здесь класс – Sportsmen базовый, класс Sportsmen1 наследует ему (является производным). В производном классе могут быть добавлены члены (поля, методы).

В данном примере в классе Sportsmen1 определено еще одно поле team.

В результате будет выведено:

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

Вопросы для самопроверки

1. Что такое класс? К какому типу относится класс? Как определить класс?

2. Каковы основные члены класса?

3. Как создать экземпляр класса?

4. Инициализация полей класса.

5. Объявление массива классов. Особенности выделения памяти под массив классов.

6. Использование конструктора экземпляра при работе с классами.

7. Что такое наследование классов и как оно реализуется?

8. Укажите основные различия между классами и структурами.

Задания для самостоятельного выполнения

Выполнить задания п. 4.1 с использованием классов, используя наследование по указанию преподавателя.

 

Методы

Метод – это последовательность инструкций (операторов) для решения какой-либо более или менее самостоятельной задачи (подзадачи), оформленная специальным образом. Методы в C# являются членами классов или структур. Первое знакомство с методами у вас уже состоялось при изучении структур. В этой главе методы будут рассмотрены более последовательно и подробно.

5.1. Общие положения.
Способы передачи параметров

Рассмотрим простейший пример.

using System;

namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

int a = 2, c = 3;

Console.WriteLine(p(a, c));

Console.ReadKey();

}

 

static int p(int a1, int c1)

{

int s = a1 + c1;

return s;

}

 

}

}

В приведенной программе в классе Program определены методы Main и p. В методе p вычисляется сумма двух переменных целого типа. Метод возвращает одно значение s, которое вычисляется в этом методе. Если метод возвращает значение, то имя переменной, в которую помещается возвращаемое значение, указывается после ключевого слова return, присутствие которого в данном случае обязательно. Если метод возвращает значение, то необходимо указать тип возвращаемого значения, в данном примере int. Таким образом, заголовок метода p включает: ключевое слово static (значение которого обсудим позже), тип возвращаемого значения int, имя метода и в скобках параметры метода с указанием их типов. Все вместе эти элементы образуют подпись метода.

Вызов метода, возвращающего значение, осуществляется указанием имени метода и в скобках аргументов метода, которые заменяют параметры метода перед его выполнением. Обращение к методу записывается в том месте кода, где требуется получить значение, возвращаемое методом. В нашем примере обращение к методу p: p(a, c) записано в операторе вывода. Аргументы, указываемые при вызове метода, должны иметь тот же тип, что и параметры метода в описании метода, и должны получить значения к моменту обращения к методу.

C# имеет две разновидности типов: типы значений и ссылочные типы (см. п. 1.1). В приведенном примере переменные a и c являются экземплярами структуры int и относятся к типу значения.

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

Так, в данном примере при обращении к методу p в ячейку для параметра a1 пересылается значение a, т.е. 2, в ячейку для параметра c1 – значение c, т.е. 3, и переменная s получает значение 5, которое и выводится в окно экрана.

Рассмотрим второй вариант решения той же задачи:

using System;

namespace ConsoleApplication1

{

class Program

{

static void Main()

{

int a = 2, c = 3, x;

ps(a, c, out x);

Console.WriteLine(x);

Console.ReadKey();

}

 

static void ps(int a1, int c1, out int s)

{

s = a1 + c1;

 

}

}

}

Те же вычисления выполняются в методе, не возвращающем значения. Если метод не возвращает значения, он имеет тип void. В списке параметров метода перечислены входные (a1, c1) и выходной (s) параметры. Ключевое слово out перед выходным параметром, имеющим тип значения, означает передачу параметра по ссылке, т.е. при обращении к методу на место выходного параметра передается адрес аргумента, фигурирующего в обращении к методу. В примере передается не значение переменной x, а адрес переменной x. Параметр s не является типом int; он является ссылкой на тип int, в данном случае ссылкой на переменную x. Поэтому после вызова метода значение переменной x изменяется.

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

Для передачи по ссылке можно использовать также ключевое словоref, но в этом случае аргумент, передаваемый по ссылке, должен быть инициирован до обращения к методу (при использовании ключевого слова out это необязательно). Ниже приводится вариант программы с использованием ref:

using System;

class Program

{

static void Main()

{

int a = 2, c = 3, x = 0;

//x присвоено фиктивное значение 0

p(a, c, ref x);

Console.WriteLine(x);

Console.ReadKey();

}

static void p(int a1, int c1, ref int s)

{

s = a1 + c1;

}

}

Замечание. Взаимное расположение методов в пределах одного класса не имеет значения. Управление всегда вначале передается методу Main.

Пример 5.1. Разработать (определить) метод для решения квадратного уравнения Вызвать метод для решения уравнения 3,2 + 4,6t – 5 = 0 и, если уравнение имеет решение, вывести на печать больший из корней. Если решения нет, вывести соответствующее сообщение.

Вариант 1. Метод root статический, методы root и Main в одном классе. Передача параметров с помощью ref:

using System;

class Program

{

static void root(double a, double b, double c,

ref double x1, ref double x2, ref bool l)

{

double d;

d = b * b - 4 * a * c;

if (d >= 0)

{

x1 = (-b + Math.Sqrt(d)) / (2 * a);

x2 = (-b - Math.Sqrt(d)) / (2 * a);

l = !l;

}

}

static void Main()

{

bool q = false;

double t1 = 0, t2 = 0, u = 0;

root(3.2, 4.6, -5.0, ref t1, ref t2, ref q);

if (q)

{

u = t1;

if (t2 > u) u = t2;

Console.WriteLine("{0} {1:f3}", q, u);

}

else

Console.WriteLine("решения нет");

Console.ReadKey();

}

}

Замечания.

1. Если два метода находятся в одном и том же классе, и один из них статический (метод Main статический по определению) и из него вызывается другой метод, то вызываемый метод должен быть статическим. Существует только одна копия статического метода. Ниже приводятся варианты (вариант 3 и вариант 4) решения этой же задачи, где использован нестатический метод (instance – экземплярный). Нестатический метод связан с экземпляром типа. Из нестатического метода можно обращаться к экземплярным полям и методам, а также к статическим полям и методам.

2. В случае использования ref переменные должны быть инициализированы до вызова. Ниже приводится листинг кода (начальные и конечные строки обрезаны) с выведенными сообщениями об ошибках, вызванных отсутствием инициализации аргументов метода, передаваемых по ссылке.

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

Вариант 2. Метод root статический, методы root и Main в одном классе. Передача параметров с помощью out. В вариантах 2, 3 и 4 возможность отсутствия решения уравнения не учитывается.



using System;

class Program

{

static void root(double a, double b, double c,

out double x1, out double x2, out bool l)

{

double d;

l = false;

d = b * b - 4 * a * c;

x1 = 0;

x2 = 0;

if (d >= 0)

{

x1 = (-b + Math.Sqrt(d)) / (2 * a);

x2 = (-b - Math.Sqrt(d)) / (2 * a);

l = !l;

}

}

static void Main()

{

bool q;

double t1, t2, u = 0;

root(3.2, 4.6, -5.0, out t1, out t2, out q);

if (q)

{

u = t1;

if (t2 > u) u = t2;

Console.WriteLine("{0} {1:f3}", q, u);

}

else

Console.WriteLine("решения нет");

Console.ReadKey();

}

}

Вариант 3. Метод root не статический и метод Main (статический) в одном классе Program:

using System;

class Program

{

void root(double a, double b, double c,

ref double x1, ref double x2, ref bool l)

{

double d;

d = b * b - 4 * a * c;

if (d >= 0)

{

x1 = (-b + Math.Sqrt(d)) / (2 * a);

x2 = (-b - Math.Sqrt(d)) / (2 * a);

l = !l;

}

}

static void Main()

{

bool q = false;

double t1 = 0, t2 = 0, u = 0;

//создается экземпляр класса

Program pr = new Program();

// pr – переменная типа Program

//метод root экземпляра pr класса Program

pr.root(3.2,4.6, -5.0, ref t1, ref t2, ref q);

if (q)

{

u = t1;

if (t2 > u) u = t2;

Console.WriteLine("{0} {1:f3}", q, u);

}

else

Console.WriteLine("решения нет");

Console.ReadKey();

}

}

Вариант 4. Методы root и Main в разных классах:

using System;

class test

{

public void root(double a, double b, double c,

ref double x1, ref double x2, ref bool l)

{

double d;

d = b * b - 4 * a * c;

if (d >= 0)

{

x1 = (-b + Math.Sqrt(d)) / (2 * a);

x2 = (-b - Math.Sqrt(d)) / (2 * a);

l = !l;

}

}

}

class Program

{

static void Main()

{

bool q = false;

double t1 = 0, t2 = 0, u = 0;

test pr = new test();

//pr – экземпляр класса test

//вызывается метод root

//экземпляра pr класса test

pr.root(3.2, 4.6,-5.0, ref t1, ref t2, ref q);

if (q)

{

u = t1;

if (t2 > u) u = t2;

Console.WriteLine("{0} {1:f3}", q, u);

}

else

Console.WriteLine("решения нет");

Console.ReadKey();

}

}

В последнем варианте метод root имеет модификатор доступа public (открытый), обеспечивающий доступ к этому методу из другого класса.

Пример 5.2. Вычислить число сочетаний из n по m: C = n!/(m!(n m)!), (в программе cnm). Вычисление факториала оформить в виде метода, возвращающего значение.

Вариант 1. Методы Main и fact для вычисления факториала в разных классах.

using System;

class test

{

public int fact (int n)

{

int f = 1;

for (int i = 2; i <= n; i++)

{

f = f * i;

}

return f;

}

}

class Program

{

static void Main()

{

int n = 4, m = 3 ;

int cnm;

test pr = new test();

cnm = pr.fact(n)/(pr.fact(m)*pr.fact(n - m));

Console.WriteLine("{0}",cnm);

}

}

Вариант 2. Методы Main и fact для вычисления факториала в одном классе:

using System;

class Program

{

static int fact(int n)

{

int f = 1;

for (int i = 2; i <= n; i++)

{

f = f * i;

}

return f;

}

static void Main()

{

int n = 5, m = 3 ;

int cnm;

cnm = fact(n)/ (fact(m) * fact(n - m));

Console.WriteLine("{0}",cnm)

Console.ReadKey();

}

}



<== предыдущая лекция | следующая лекция ==>
Использование структур | Использование массивов в качестве параметров


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.175 сек.