c#2_oop
.pdfВведение в ООП
Опорный конспект для самостоятельной работы
Цель: - изучение теоретических основ ООП; формирование практических навыков создания классов, полей, свойств, методов, конструкторов, объектов на языке C# в среде MS Visual Studio.
Учебный модуль включает:
∙лекцию, содержащую теоретический материал с демонстрацией практических примеров (2ч);
∙практические занятия, проводимые в форме лабораторных работ, содержащих упражнения, примеры их выполнения и задания (4 ч);
∙самостоятельную работу, предусматривающую изучение теоретического материала, подготовку к практическим занятиям и выполнение индивидуальных заданий (проектов) (4ч).
Текущий контроль осуществляется в ходе выполнения практических (лабораторных) работ (проектов).
Понятие объекта
Вреальном мире каждый объект обладает свойствами и поведением (набором статических и динамических характеристик). Поведение объекта зависит от его состояния и внешних воздействий.
Впрограммировании понятие объекта похоже на обыденный смысл этого слова
∙Объект представляется как совокупность данных, характеризующих его состояние, и методов их обработки, моделирующих его поведение.
∙В объектно-ориентированном программировании предметная область представляется как совокупность взаимодействующих объектов.
∙Реализуется событийная модель взаимодействия объектов: объекты обмениваются сообщениями и, реагируя на них, выполняют действия.
Проработать теоретический материал [1-3], привести примеры.
Абстрагирование. Инкапсуляция
При представлении реального объекта в программе необходимо выделить его существенные особенности и игнорировать несущественные.
∙Абстрагирование - выделение существенных и отбрасывание второстепенных для данной задачи свойств. Программный объект — это абстракция (привести примеры).
Детали реализации объекта скрыты, они используются через его интерфейс — совокупность
правил доступа.
∙Инкапсуляция (encapsulation) - сокрытие деталей реализации.
Позволяет представить программу в укрупненном виде — на уровне объектов и их взаимосвязей, и, следовательно, управлять большим объемом информации.
∙Объект — это инкапсулированная абстракция с четко определенным интерфейсом.
Наследование
∙Наследование (inheritance) - это процесс, посредством которого один объект может приобретать свойства другого.
Наследование дает возможность многократного использования программного кода.
Для объекта можно определить наследников, корректирующих и/или дополняющих его поведение.
∙Наследование применяется для:
-исключения из программы повторяющихся фрагментов кода;
-упрощения модификации программы;
-упрощения создания новых программ на основе существующих.
∙Благодаря наследованию появляется возможность использовать объекты, исходный код которых недоступен, но в которые требуется внести изменения.
∙Наследование позволяет создавать иерархии объектов. Иерархия представляется в виде дерева, в котором более общие объекты (предки) располагаются ближе к корню, а более специализированные (наследники)— на ветвях и листьях.
Проработать теоретический материал [1-3], привести примеры иерархии классов .NET
Полиморфизм
∙Полиморфизм – использование одного имени (методов, операций, объектов)
для решения нескольких схожих задач или для обращения к объектам разного типа. Идея полиморфизма: "один интерфейс, множество методов".
∙Реализации полиморфизма: перегрузка методов, перегрузка операций, виртуальные методы, переопределение методов, параметризованные классы.
Чаще всего понятие полиморфизма связывают с механизмом виртуальных методов.
Понятие класса
∙Класс - обобщенное понятие, описывающее характеристики и поведение множества сходных объектов (называемых экземплярами этого класса).
∙В программе класс является типом данных, определяемым пользователем.
∙Представляет собой фрагмент программы, описывающий одну логическую сущность, например, модель реального объекта или процесса.
∙Элементами (members) класса являются данные и методы их обработки.
Все классы .NET имеют общего предка — класс object, и организованы в единую иерархическую структуру. Классы логически группируются в пространства имен, которые служат для упорядочивания имен классов и предотвращения конфликтов имен: в разных пространствах имена могут совпадать. Пространства имен могут быть вложенными. Любая программа использует пространство имен System.
Описание класса
[ модификаторы ] class имя [ : предки ]
{ тело класса }
Имя класса задается по общим правилам языка C#.
Тело класса — описания его элементов { в фигурных скобках }.
Модификаторы (modifier) определяют свойства класса, а также доступность для других элементов программы: internal - внутренний (по умолчанию, можно опустить);
public – общедоступный; protected – защищенный; protected internal; private – закрытый; static – статический; abstract – абстрактный; sealed – бесплодный;
Составить таблицу описаний модификаторов с указанием области применения [1-3].
|
Таблица 1. Модификаторы класса |
|
|
Модификатор |
Описание |
|
|
internal |
Доступ только из данной программы или сборки (по умолчанию) |
|
|
|
|
public |
Общедоступный класс. Доступ не ограничен |
|
|
protected |
Защищенный класс. Доступ только из элементов данного и производных |
|
классов |
|
|
|
|
protected internal |
Доступ только из данного и производных классов |
|
или из данной программы или сборки |
|
|
|
|
new |
Задает новое описание класса взамен унаследованного от предка. |
|
Применяется в иерархиях (для вложенных классов). |
|
|
|
|
private |
Закрытый класс (для вложенных классов). |
|
Доступ только из описанных в нем элементов |
|
|
static |
Статический класс. |
|
|
abstract |
Абстрактный класс. Применяется в иерархиях |
|
|
|
|
sealed |
Бесплодный класс. Применяется в иерархиях |
|
|
|
|
|
Простейшие примеры описания класса |
|
class Demo { } |
//пустой класс, доступность по умолчанию internal |
|
public class Computer |
// общедоступный класс с одним методом |
|
{ public void ShowInfo() |
|
|
{ Console.WriteLine( " RAM = 1024 " ) ; } |
} |
Привести примеры использования всех модификаторов [1-3].
Состав класса
Класс может содержать следующие функциональные элементы (members):
∙поля - характеристики класса (как правило, скрытые private);
∙ |
свойства - обеспечивают “ умный” доступ к полям; |
∙ |
конструкторы - определяют инициализацию объектов (экземпляров класса); |
∙методы - определяют поведение класса;
∙набор операций, позволяющих копировать, присваивать, сравнивать объекты
ипроизводить с ними другие действия, требующиеся по логике класса;
∙исключения – используются для сообщений об ошибках путем генерации исключений. Методы реализуют функционал класса. Каждый метод класса должен решать только одну задачу. Необходимо четко представлять, какие параметры метод должен получать и какие результаты формировать. Необходимо стремиться к максимальному сокращению области действия каждой переменной. Это упрощает отладку программы, поскольку ограничивает область поиска ошибки. Элементы (поля, методы), характеризующие класс в целом, следует описывать как статические.
Составить таблицу (схему) элементов классов (см рис [1]). Привести примеры.
Описание объекта (экземпляра класса)
Класс является обобщенным понятием, определяющим характеристики и поведение множества конкретных объектов, называемых экземплярами (объектами) этого класса.
Классы создаются программистом до выполнения программы. Экземпляры класса (объекты) создаются системой во время выполнения. Программист задает создание экземпляра класса с помощью операции new:
Computer comp1 = new Computer();
Computer comp2 = new Computer(“IBM”, 2048);
Для каждого объекта при его задании в памяти выделяется отдельная область для хранения его данных. Кроме того, в классе могут присутствовать статические элементы, которые существуют в единственном экземпляре.
Разобрать примеры описаний классов и экземпляров [1-3].
Данные: поля и константы
Содержащиеся в классе данные могут быть переменными или константами.
∙Переменные, описанные в классе, называются полями класса.
При описании полей обязательно указывают тип и имя; можно также указывать атрибуты и модификаторы, задающие доступность и другие характеристики
[модификаторы ] [ const ] тип имя [ = начальное_значение ]
Примеры: public int |
a = 27; public static string str = "программа"; |
double y; |
//по умолчанию закрытое поле данных (private) |
Составить таблицу описаний модификаторов полей и констант класса [1-3].
∙Все поля в C# сначала автоматически инициализируются нулем соответствующего типа.
Например, полям типа int присваивается 0, double 0.0 , а ссылкам на объекты — значение null). После этого полю присваивается значение, заданное при его явной инициализации.
using System; Примеры классов class Brosok
{ public const double g = 9.81;
public int t = 12;
public double v;
public static string s = “ Скорость";
double z; } class Program {
static void Main() {
Brosok br = new Brosok();
|
Console.WriteLine( br.t ); |
|
Console.WriteLine(Brosok.g ); |
|
Console.WriteLine(Brosok.s ); |
} |
} |
//константа
//общедоступные поля
//статическое поле класса
//закрытое поле данных (private)
//создание экземпляра класса Brosok
//обращение к полю
//обращение к константе
//обращение к статическому полю
Проработать теоретический материал [1-3], привести примеры.
Методы
∙Метод — функциональный элемент класса, реализующий вычисления или другие действия. Методы определяют поведение класса и составляют его интерфейс.
∙Метод в программе — законченный фрагмент кода, к которому можно обратиться по имени. Он описывается один раз, а вызываться может многократно при необходимости. Один и тот же метод может обрабатывать различные данные, переданные ему в качестве аргументов.
Описание метода
[ модификаторы ] тип имя( [параметры] ) { тело метода }
Модификаторы, задающие доступность и другие характеристики:
public, private, protected, internal, protected internal; abstract, virtual, override, new, static, sealed.
Составить таблицу описаний модификаторов [1-3]. Привести примеры.
class Calc |
|
|
|
{ |
public static void Privet() |
|
//определение общедоступного статического метода void |
|
{ Console.WriteLine("Привет"); } |
||
|
public int Area(int a, int b) |
// определение закрытого метода int |
|
|
{ return (a*b); } |
} |
|
class Program |
|
|
|
{ |
static void Main() |
|
|
|
{ Prog.Privet(); |
|
//вызов статического метода, определенного в другом классе |
|
Calc ar = new Calc(); |
|
//создание объекта ar – экземпляра класса Calc |
|
int s = ar.Area(4, 6); } |
} |
//вызов метода объекта ar |
Проработать теоретический материал [1-3], привести примеры.
Метод класса имеет непосредственный доступ к его полям или через set – get (свойства).
public void SetY(int x) |
{ y = x; } |
|
public int GetY() |
{ |
return y; } |
Параметры методов
Параметры определяют множество значений аргументов, которые можно передавать в метод.
∙Для каждого параметра должны задаваться его тип и имя.
∙Список аргументов при вызове как бы накладывается на список параметров, поэтому они должны попарно соответствовать друг другу.
∙Имя метода вместе с типами и модификаторами его параметров составляет сигнатуру метода. Методы в классе различают благодаря сигнатуре. В классе не должно быть методов с одинаковыми сигнатурами.
∙Метод со спецификатором static, должен обращаться только к статическим полям класса.
Статический метод вызывается через имя класса, а обычный — через имя экземпляра.
При вызове метода:
∙Выделяется память под параметры метода.
∙Каждому из параметров сопоставляется соответствующий аргумент. Проверяется соответствие типов аргументов и параметров и при необходимости выполняется их преобразование. (при невозможности выдается диагностическое сообщение).
∙Выполняются вычисления и/или другие действия (тело метода).
∙Если метод возвращает значение, оно передается в точку вызова; если метод имеет тип void, управление передается на выражение, следующее после вызова.
class SomeClass |
|
{ static int Max(int a, int b) |
// метод выбора максимального значения |
{ return a > b ? a : b ; |
} |
static void Main() |
|
{ |
|
int a=2, b=4; |
|
int x=Max(a, b); |
// вызов метода |
Console.WriteLine(x); |
// результат: 4 |
short d=5, e=3; |
|
int y=Max(d,e); |
// аргументы совместимого типа |
Console.WriteLine(y); |
// результат: 5 |
int z = Max(a+d, b*e); |
// аргументы-выражения |
Console.WriteLine(z); |
// результат: 12 |
} |
|
} |
|
Проработать теоретический материал [1-3], привести примеры вызова методов с разными параметрами.
Перегрузка методов
∙Перегрузкой методов (overloading) называется использование методов с одним и тем же именем, но различным количеством и типами параметров.
∙Компилятор определяет, какой именно метод требуется вызвать, по типу фактических параметров. Это называется разрешением (resolution) перегрузки.
int max( int a, int b ) |
// возвращает наибольшее из двух целых |
int max( int a, int b, int c ) |
// возвращает наибольшее из трех целых |
int max ( int a, string s ) |
// возвращает наибольшее из параметра a и длины строки s |
Console.WriteLine( max( 1, 2 ) ); |
// 2 |
Console.WriteLine( max( 1, 2, 3 ) ); |
// 3 |
Console.WriteLine( max( 1, "12345" ) ); |
// 5 |
∙Перегрузка методов - проявление полиморфизма
Проработать теоретический материал [1-3], привести примеры перегрузки методов ( см. пример 2 лаб работы 06)
Способы передачи аргументов в метод. Типы параметров
В С# четыре типа параметров:
∙параметры-значения -для исходных данных метода;
∙параметры-ссылки (ref) - для изменения аргумента;
∙выходные параметры (out) - для формирования аргумента;
∙параметры-массивы (params) - для переменного количества аргументов.
Правила применения параметров
∙Для параметров-значений используется передача по значению. Этот способ применяется для исходных данных метода.
∙При вызове метода на месте аргумента параметра-значения может быть выражение (а также его частные случаи — переменная или константа). Должно существовать неявное преобразование типа выражения к типу параметра.
∙Параметры-ссылки и выходные параметры передаются по адресу. Этот способ применяется для передачи побочных результатов метода.
∙При вызове метода на месте аргумента параметра-ссылки ref может находиться только имя инициализированной переменной точно того же типа. Перед именем параметра и аргумента указывается ключевое слово ref.
∙При вызове метода на месте выходного параметра out может находиться только имя переменной точно того же типа. Ее инициализация не требуется. Перед именем параметра и
аргумента указывается ключевое слово out.
Проработать теоретический материал [1-3], привести примеры передачи аргументов.
Передача аргументов: параметры-значения и ссылки ref:
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, ref b ); |
|
|
Console.WriteLine( "после вызова {0} {1}", a, b ); |
} } |
|
Использование выходных параметров out: |
|
|
class Class2 |
|
|
{ static void P( int x, out int y ) |
|
|
{ x = 44; y = 33; |
|
|
Console.WriteLine( "внутри метода {0} {1}", x, y ); |
} |
|
static void Main() |
|
|
{ int a = 2, b; |
// инициализация b не требуется |
|
P( a, out b ); |
|
|
Console.WriteLine( "после вызова {0} {1}", a, b ); |
} } |
Методы с переменным количеством аргументов, как правило, требуют обработки исключений:
class Class3
{public static double Average( params int[] a )
{ if ( a.Length == 0 ) throw new Exception( "Недостаточно аргументов");
double sum = 0;
foreach ( int elem in a ) sum += elem; return sum / a.Length; }
static void Main() |
|
|
|
|
|
|
|
{ try |
|
|
|
|
|
|
|
{ short z = 1, e = 13, w = 4; |
Console.WriteLine( Average( z, e, w ) ); |
// |
6 |
||||
byte v = 18; |
Console.WriteLine( Average( z, e, w, v) ); |
|
// |
9 |
|||
int[] b = { -11, -4, 12, 14, 32, -1, 28 }; |
Console.WriteLine( Average( b ) ); |
// 38 |
|||||
Console.WriteLine( Average() ); |
} |
// недостаточно аргументов |
|||||
catch( Exception e ) { Console.WriteLine( e.Message ); return; } |
|
|
|
||||
catch |
{ Console.WriteLine( "ошибка" ); return; } |
} } |
|
|
Конструкторы
∙Конструктор – особый вид метода, предназначенный для инициализации объекта (конструктор экземпляра) или класса (статический конструктор).
Конструктор объекта инициализирует данные экземпляра. Конструктор класса — данные класса. Конструктор объекта вызывается при создании экземпляра класса с помощью ключевого слова new. Имя конструктора совпадает с именем класса.
Свойства конструкторов
∙Конструктор не возвращает значение, даже типа void.
∙Класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации.
∙Если не указано ни одного конструктора или некоторые поля не были инициализированы, полям значимых типов присваивается нуль (0, 0.0), полям ссылочных типов — значение null.
∙Конструктор, вызываемый без параметров, называется конструктором по умолчанию.
Проработать теоретический материал [1-3], привести примеры создания и использования конструкторов ( см. пример 1 лаб работы 06; пример 2 лаб работы 07).
Статические конструкторы
∙Статический конструктор (конструктор класса) инициализирует статические поля класса.
∙Он не имеет параметров, его нельзя вызвать явным образом.
∙Система сама определяет момент, в который требуется его выполнить. Это происходит до создания первого экземпляра объекта и до вызова любого статического метода.
∙Статический конструктор, как любой статический метод, не имеет доступа к полям объекта.
Привести примеры статических конструкторов [1-3],
Свойства
∙ Свойства (properties) служат для организации доступа к полям класса. Как правило, свойство определяет методы доступа к закрытому полю.
Свойства обеспечивают разделение между внутренним состоянием объекта и его интерфейсом.
Синтаксис: [ модификаторы] |
тип имя |
|
|
||
{ |
{ |
get |
код_доступа |
} |
|
|
{ |
set |
код_доступа |
} |
} |
При обращении к свойству автоматически вызываются указанные в нем блоки чтения (get) и установки (set). Может отсутствовать либо часть get, либо set, но не обе одновременно.
Если отсутствует set, свойство доступно только для чтения (read-only), если отсутствует get - только
для записи (write-only). |
|
|
|||
public class Letter |
|
|
|||
{ |
private string caption; |
// закрытое поле |
|||
|
public string Caption { |
// общедоступное свойство |
|||
|
{ get |
{ |
return caption; } |
// способ получения свойства |
|
|
set |
{ |
if (caption != value) |
caption = value; } |
// способ установки свойства |
} |
} |
|
|
|
|
Проработать теоретический материал [1-3], привести примеры создания и использования свойств ( см. пример 1 лаб работы 07).
Операции класса. Перегрузка операций
∙В языке С# можно переопределить большинство стандартных операций для своих классов. Это позволяет применять свои объекты (экземпляры класса пользовательского типа) в составе выражений аналогично переменным стандартных типов, например:
MyObj a, b, c; ... |
|
c = a + b; |
// операция сложения объектов класса MyObj |
∙Определение собственных операций класса называют перегрузкой операций.
Операции класса описываются с помощью методов специального вида (функций-операций): public static имя_класса operator операция( параметры ) {… }
Например: public static MyObj operator + ( MyObj m ) { … }
В языке C# три вида операций класса: унарные, бинарные и операции преобразования типа.
Правила описания операций класса
∙операция описывается как открытый статический метод класса (модификаторы public static);
∙параметры в операцию должны передаваться по значению (то есть не должны предваряться ключевыми словами ref или out);
∙сигнатуры всех операций класса должны различаться;
∙типы, используемые в операции, должны иметь не меньшие права доступа, чем сама операция (т.е. должны быть доступны при использовании операции).
Повторить типы данных, проработать теоретический материал [1-3]. Рассмотреть особенности переопределения унарных и бинарных операций.
Унарные операции |
|
Можно переопределять: + - ! ~ ++ -- true |
false |
например: public static MyObj operator -- ( MyObj m ) |
// декремент |
Особенности переопределения унарной операции: |
|
∙Параметр функции-операции должен иметь тип этого же класса.
∙Операция должна возвращать: для операций +, -, ! и ~ величину любого типа; для операций ++ и -- величину типа класса, для которого она определяется.
∙Операции не должны изменять значение передаваемого им операнда.
Операция, возвращающая данные типа класса должна создать новый объект этого класса, выполнить с ним необходимые действия и передать его в качестве результата.
∙Префиксный и постфиксный инкремент/декремент не различаются
class Dog |
|
|
{ public static Dog operator ++ (Dog d) |
// инкремент |
|
{ Dog tmp = new Dog (d.ves+1, d.rost+2, d.name); |
|
|
return tmp; } |
} |
|
Dog amur = new Dog(); |
amur++; |
|
Разобрать примеры переопределения унарных операций [1-3].
Бинарные операции |
|
Можно переопределять: + - * / % & | ^ << >> == != |
> < >= <= , |
например: public static MyObj operator + ( MyObj m1, MyObj m2 ) |
// сложение |
public static bool MyObj operator == ( MyObj m1, MyObj m2 ) |
// сравнение |
Особенности переопределения бинарной операции: |
|