Автор работы: Пользователь скрыл имя, 12 Декабря 2014 в 15:28, доклад
В языке С# все программы и данные представляют собой объекты, а все обрабатывающие их алгоритмы являются методами. Оба этих понятия имеют самое непосредственное отношение к ООП.
Владение методикой ООП абсолютно необходимо для успешного программирования на языке С#. Фактически, не разобравшись в этом, вы не сможете создавать на С# хоть сколько-нибудь сложные программы и системы.
Поля и методы, а также другие объекты, объявленные в классе, часто называют членами класса (class members). Мы тоже будем пользоваться этой терминологией.
Создание объектов класса TelevisionSet
Теперь у нас есть класс TelevisionSet — описание телевизора, но нет самого
телевизора. Пользуясь нашим классом, мы сможем создать необходимое нам количество телевизоров. Допустим, нам нужны два телевизора, большой, способный принимать до 40 каналов, и маленький, рассчитанный на прием шести каналов. Прежде всего для создания объектов-телевизоров необходимо объявить в программе две переменные типа TelevisionSet:
TelevisionSet tvSmall;
TelevisionSet tvLarge;
Как видите, объявление выглядит аналогично объявлению числовых или строчных переменных, с той лишь разницей, что вместо одного из стандартных типов данных С# мы использовали здесь определенный нами тип данных TelevisionSet. На самом деле есть еще одно отличие. В то время как стандартные типы данных можно использовать в программе сразу после объявления, объекты других классов нужно создавать явным образом при по-
помощи ключевого слова new:
tvSmall = new TelevisionSet(6) ;
tvLarge = new TelevisionSet(40) ;
Здесь мы создали два объекта, вызвав их конструкторы. При первом вызове мы передали конструктору значение 6, а при втором — значение 40. В результате всех этих действий программа записала в переменные tvSmall
и tvLarge так называемые ссылки на объекты. Переменная tvSmall ссылается
на объект-телевизор, способный принимать 6 каналов, а переменная tvLarge –
на 40-канальный телевизор. Важно, что для создания этих разных телевизоров мы использовали один и тот же класс, т. е. одно и то же описание объекта.
Отсюда наглядно видно различие между классом и объектом. Класс представляет собой описание объекта, а объект — это реально существующая в памяти компьютера сущность, с которой программа может выполнять какие-либо действия.
Вызов методов класса
После того как программа создала объекты, она может вызывать методы, определенные в классе этих объектов. Вызвать метод очень просто:
tvSmall.SetPowerStateOn();
tvSmall.SetChannel(5);
tvSmall.SetVolume(50);
tvLarge.SetPowerStateOn();
tvLarge.SetChannel(27);
tvLarge.SetVolume(30);
Здесь мы указали имя переменной, содержащей ссылку на объект, а затем через точку — имя вызываемого метода. Если метод принимает параметры, эти параметры следует указать в скобках. Вызывая одни и те же методы для разных объектов, мы выполняем с этими объектами одни и те же действия. Например, метод SetPowerStateOn включает наши телевизоры:
tvSmall.SetPowerStateOn();
tvLarge.SetPowerStateOn{);
Чтобы переключить телевизоры на разные каналы, достаточно при вызове метода SetChannel передать ему разные параметры:
tvSmall.SetChannel(6);
tvLarge.SetChannel(27);
Первый телевизор будет переключен на 6-й канал, а второй — на 27-й канал. Аналогичным образом вы можете изменять громкость каждого телевизора, вызывая для соответствующих объектов метод SetVolume:
tvSmall.SetVolume(50);
tvLarge.SetVolume(30);
Если метод возвращает значение, оно может быть присвоено переменной или использовано в выражении. Вот, например, как можно узнать текущий номер канала и текущий уровень громкости наших телевизоров:
byte chSmall = tvSmall.GetChannel();
byte volSmall= tvSmall.GetVolume());
byte chLarge = tvLarge.GetChannel () ;
byte volLarge = tvLarge.GetVolume()) ;
После выполнения этих строк в переменных chSmall и volSmall будут записаны текущие значения номера канала и громкости первого телевизора, а в переменных chLarge и volLarge — второго. Заметим, что программа, создавшая объект, может обращаться только к таким методам, которые объявлены в описании класса со спецификатором доступа public.
Обращение к полям класса
С помощью ссылки на объект программа может не только вызывать методы класса, но и обращаться напрямую к его полям (если, конечно, они определены со спецификатором доступа public, разрешающим такое обращение).
Вот, например, как можно узнать максимальное количество каналов,
предусмотренное в наших телевизорах:
byte maxChannelSmall = tvSmall.maxChannel;
byte maxChannelLarge - tvLarge.maxChannel;
При необходимости программа сможет изменить максимальное количество
каналов уже после создания телевизора:
tvSmall.maxChannel = 10;
tvLarge.maxChannel = 150;
Заметим, что максимальное количество каналов можно безболезненно увеличивать, в то время как уменьшение следует выполнять осторожно. Например, если телевизор переключен на 10-й канал, а вы устанавливаете максимальный номер канала, равный, скажем, пяти, то возникнет ошибочная ситуация — телевизор должен показывать канал с недопустимым номером. Для избежания логических ошибок подобного рода лучше возложить задачу изменения полей класса на методы, определенные в классе. Эти методы будут учитывать вес особенности работы с объектом. В случае нашего телевизора перед уменьшением максимального количества каналов такой метод мог бы, например, установить номер текущего канала равным единице.
Лучше всего, если методы класса будут реализовывать всю внутреннюю логику поведения объекта. При этом программист, составляющий программу для работы с объектом, может не отвлекаться на особенности внутреннего устройства объекта и его реализации. Это позволит сконцентрировать внимание на других, более важных задачах и снизить количество ошибок, допускаемых в процессе программирования. Способность объекта скрывать детали своей внутренней реализации и внутренней логики работы от вызывающих программ называется инкапсуляцией. Инкапсуляция — один из китов, на которых базируется ООП.
Пример программы
Ранее мы привели полный исходный текст программы, в которой определен рассмотренный выше класс TelevisionSet. Эта программа демонстрирует процедуру создания объектов на базе определенных нами классов, обращение к методам и полям класса.
using System;
namespace TvSet
{
class TelevisionSet
{
bool isPowerOn,- // включен или выключен
byte maxChannel; // максимальный номер канала
byte currentchannel; // текущий номер канала
byte currentVolume; // текущая громкость звука
// Конструктор класса TelevisionSet
public TelevisionSet(byte numberOfChannels)
{
// Устанавливаем исходное состояние телевизора
isPowerOn = false; // выключен
maxChannel = numberOfChannels; // макс, количество каналов
currentchannel= 1; // при включении показывать канал 1
currentVolume = 10; // громкость при включении - 10%
}
// Включить телевизор
public void SetPowerStateOn()
{
isPowerOn = true;
// Выключить телевизор
public void SetPowerStateOff()
{
isPowerOn = false;
// Определить состояние телевизора - включен или выключен
public bool GetPowerState()
{
return isPowerOn;
// Переключиться на прием заданного канала
public bool SetChannel(byte channel)
{
if(channel <= maxChannel && channel > 0)
{
currentChannel = channel;
return true;
}
else
return false;
// Получить номер текущего канала
public byte GetChanneK)
{
return currentChannel;
// Установить громкость
public void SetVolumefbyte volume)
{
if(volume > 0 && volume <= 100)
currentVolume = volume;
else
currentVolume = 0;
// Получить текущий уровень громкости
public byte GetVolumeO
{
return currentVolume;
class TvSetApp
{
static void Main(string[] args)
{
TelevisionSet tvSmall;
TelevisionSet tvLarge ,-
tvSmall = new TelevisionSetF);
tvLarge = new TelevisionSetD0);
tvSmall.SetPowerStateOn();
tvSmall.SetChannelE);
tvSmall.SetVoluroeE0);
tvLarge.SetPowerStateOn();
tvLarge.SetChannelB7);
tvLarge.SetVolumeC0);
Console.Write("Телевизор tvSmall: ");
Console.WriteLine("{0}, канал {1} из {2}, громкость {3}",
tvSmall.GetPowerState() ? "Включен" : "Выключен",
tvSmall.GetChannel(), tvSmall.maxChannel,
tvSmall.GetVolume());
Console.Write("Телевизор tvLarge: ");
Console.WriteLine("{0}, канал {1} из {2}, громкость {3}",
tvLarge.GetPowerState() ? "Включен" : "Выключен",
tvLarge.GetChannel(), tvLarge.maxChannel,
tvLarge.GetVolume());
tvSmall.SetChannelC);
tvSmall.SetVolume(80);
tvLarge.SetChannelC9);
tvLarge.SetVolumeF0);
tvSmall.SetPowerStateOff();
tvLarge.SetPowerStateOff();
Console.Write("ХпТелевизор tvSmall: ");
Console.WriteLine("{0}, канал {1} из {2}, громкость {3}",
tvSmall.GetPowerState() ? "Включен" : "Выключен",
tvSmall.GetChannel(), tvSmall.maxChannel,
tvSmall.GetVolume());
Console.Write("Телевизор tvLarge: ");
Console.WriteLine("{0), канал {1} из {2}, громкость {3}
tvLarge.GetPowerState() ? "Включен" : "Выключен",
tvLarge.GetChannel(), tvLarge.maxChannel,
tvLarge.GetVolume());
Console.ReadLine();
В самом начале листинга находится объявление класса TelevisionSet, о котором мы уже рассказывали раньше. Назначение полей и методов этого класса было подробно описано, поэтому мы не будем повторяться. Нам хотелось бы обратить ваше внимание на то, как в этой программе мы вызываем методы Write и WriteLine:
Console.Write("Телевизор tvSmall: ");
Console.WriteLine("{0}, канал {1} из {2}, громкость {3}",
tvSmall.GetPowerState() ? "Включен" : "Выключен",
tvSmall.GetChannel(), tvSmall.maxChannel,
tvSmall.GetVolume());
Обратите внимание, что при вызове этих методов мы опустили пространство имен System. Это вполне допустимо, так как в начале нашей программы имеется строка с оператором using, предписывающая компилятору С# просматривать это пространство имен: using System;
В дальнейшем при частом обращении к методам, определенным в рамках какого-либо пространства имен, мы будем опускать имя пространства имен при вызове метода, одновременно указывая его с помощью оператора using. Так наши программы будут короче и проще для понимания. В своих проектах вы можете поступать как угодно в зависимости от собственных предпочтений.
Теперь о том, что делает наша программа.
Получив управление, метод Main создает два виртуальных телевизора, один из которых (маленький) способен принимать 6 каналов, а другой (большой) — 40 каналов:
TelevisionSet tvSmall;
TelevisionSet tvLarge;
tvSmall = new TelevisionSet(6);
tvLarge = new TelevisionSet(40);
Далее наша программа включает по очереди оба телевизора, устанавливая на первом из них 5-й канал, а на втором — 27-й канал. Уровень громкости тоже
устанавливается разный:
tvSmall.SetPowerStateOn();
tvSmall.SetChannel(5) ;
tvSmall.SetVolume(50);
tvLarge.SetPowerStateOn();
tvLarge.SetChannel(27);
tvLarge.SetVolume(30);
После этого программа отображает текущее состояние обоих телевизоров на консоли. На следующем этапа программа вновь изменяет номера текущих каналов и уровень громкости обоих телевизоров, а затем выключает их вовсе:
tvSmall.SetChannel(3);
tvSmall.SetVolume(80);
tvLarge.SetChannel(39);
tvLarge.SetVolume(60);
tvSmall.SetPowerStateOff();
tvLarge.SetPowerStateOff();
И наконец, перед завершением своей работы программа отображает новое
состояние телевизоров на консоли:
Телевизор tvSmall: Включен, канал 5 из б, громкость 50
Телевизор tvLarge: Включен, канал 27 из 40, громкость 30
Телевизор tvSmall: Выключен, канал 3 из 6, громкость 80
Телевизор tvLarge: Выключен, канал 39 из 40, громкость 60
Таким образом, разработав класс, описывающий поведение телевизора, мы создали два объекта этого класса, а затем управляли этими объектами совершенно независимо. Этот принцип можно обобщить на данные любого типа. Пользуясь объектно-ориентированными средствами С#, мы можем описать с помощью классов данные любых типов, а затем на базе этих классов создавать объекты.
Наследование
После того как мы сделали первые шаги в освоении ООП и разобрались с первой объектно-ориентированной программой, настало время дать более строгие определения терминов и понятий ООП. В этом разделе мы займемся классами. Теперь вы знаете, что классы позволяют объединить вместе данные и методы, предназначенные для их обработки. Создав объекты того или иного класса, программа может вызывать методы и обращаться напрямую к полям объекта (если это разрешено при объявлении класса). Работая с объектами, созданными на базе классов, программисту нет нужды вникать во внутренние детали устройства класса— достаточно знать, как и какие методы можно вызывать, какие передавать им параметры и какие значения эти методы возвращают. Механизм сокрытия, или, как говорят, инкапсуляции, данных и методов класса облегчает создание программ, особенно сложных, так как позволяет программисту не вникать во все детали реализации всех программных компонентов. В этом разделе мы рассмотрим другое базовое понятие ООП, а именно наследование. С этим понятием неразрывно связаны два других понятия — базовый класс и производный класс.
Базовый класс
Наследование позволяет создавать новые классы на базе уже существующих классов. Создавая новый тип данных на базе типа данных, определенного ранее, можно упростить работу за счет использования разработанных ранее методов базового класса. Базовым (base), или родительским (parent), классом называется класс, на основе которого создаются другие классы. Чтобы это определение было понятнее, рассмотрим следующий пример.
Пусть нам нужно работать в программе с такими объектами, как прямоугольники. Для этого мы создаем класс Rectangle, инкапсулирующий в себе данные и методы, необходимые для размещения прямоугольника на плоскости:
class Rectangle
{
int xPos;
int yPos;
int width;
int height;
public Rectangle()
{
xPos = yPos = width = height = 0;
public void SetPosition(int x, int y)
{
public void SetPosition(int x, int y)
{
xPos = x;
yPos = y;
}
public void SetSize(int w, int h)
{
Информация о работе Объектно-ориентированное программирование