39
Темы лекции: ООП на C#. Практическое задание: ООП на C#. Тренер: Игорь Шкулипа, к.т.н. Платформа .Net и язык программирования C#. Занятие 2

C# Desktop. Занятие 02

Embed Size (px)

Citation preview

Темы лекции: ООП на C#.

Практическое задание: ООП на C#.

Тренер: Игорь Шкулипа, к.т.н.

Платформа .Net и язык программирования C#.

Занятие 2

http://www.slideshare.net/IgorShkulipa 2

Определение классов

public class Base

{

public Base()

{ }

protected int x;

}

[Serializable]

public class Derived: Base, ICloneable

{

private Derived(Derived arg)

{ this.x = arg.x; }

public object Clone()

{ return new Derived(this); }

}

http://www.slideshare.net/IgorShkulipa 3

Модификаторы доступа

Модификатор Значение

public Член является общедоступным. Доступ никак не ограничен.

protected Член виден классу, в котором он определен и всем классам-наследникам

internal Член виден везде в пределах содержащей его сборки.

protected internal Является комбинацией protected и internal с операцией «ИЛИ»

private Член виден только классу, в котором он определен.

http://www.slideshare.net/IgorShkulipa 4

Модификаторы доступа

Модификатор Значение

static Член является членом класса, то есть общим для всех экземпляров.

readonly Определяет поле, доступное только для чтения.

const Константное поле.

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

http://www.slideshare.net/IgorShkulipa 5

Поля и методы

Поля (data members) хранят всю необходимую информацию обобъекте, формируют его состояние, характеристики и т.п.

Методы (methods) – программный код, выполненный в видефункции, реагирующий на передачу объекту определенногосообщения.

http://www.slideshare.net/IgorShkulipa 6

Свойства

Свойства реализуют сокращенную нотацию для средств доступа к даннымкласса.

class GetSetExample {

private int x; private int y;

public int X

{ get {

Console.WriteLine("Getting X...\n");

return x; }

set {

Console.WriteLine("Setting X...\n");

x = value; }

}

public int Y { get {return y;}; set {y=value;}; }

}

class Program {

static void Main(string[] args) {

GetSetExample gse = new GetSetExample();

gse.X = 2; gse.Y = 3;

Console.WriteLine("X={0}", gse.X);

Console.WriteLine("Y={0}", gse.Y);

Console.ReadKey();

}}

http://www.slideshare.net/IgorShkulipa 7

Свойства

Если для свойства определено только средство get, то такое свойствобудет доступно только для чтения.

Если для свойства определено только средство доступа set, то такоесвойство будет доступно только для записи.

В С# 3.0 добавлены автореализуемые свойства:

class GetSetExample

{

public int X { get; set; }

public int Y { get; set; }

}

При автореализуемых свойствах компилятор генерирует приватное поледля хранения этой информации.

http://www.slideshare.net/IgorShkulipa 8

Передача параметров методам

По умолчанию, параметры методу передаются по значению.

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

Для использования параметра ref и определение метода и при вызовеметода необходимо явно использовать ключевое слово ref.

static void Method(ref int i) {}

static void Main() {

int val = 1;

Method(ref val);

}

Аргументы, передаваемые в параметры ref должны бытьинициализированы, прежде чем переданы. Это отличается отпараметров out - аргументы, которые не должны быть явноинициализированы, прежде чем они передаются.

http://www.slideshare.net/IgorShkulipa 9

Ключевое слово params

Ключевое слово params позволяет определить параметр метода,принимающий переменное количество аргументов.

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

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

public class MyClass

{

public static void UseParams(params int[] list){ }

public static void UseParams2(params object[] list) { }

static void Main() {

UseParams(1, 2, 3, 4);

UseParams2(1, 'a', "test");

UseParams2();

int[] myIntArray = { 5, 6, 7, 8, 9 };

UseParams(myIntArray);

object[] myObjArray = { 2, 'b', "test", "again" };

UseParams2(myObjArray); }

}

http://www.slideshare.net/IgorShkulipa 10

Герметизированные классы

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

public sealed class SealedClass : Base

{

public int X

{

get { return x; }

set { x = value; }

}

}

http://www.slideshare.net/IgorShkulipa 11

Абстрактные классы

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

public abstract class Base

{

public Base()

{ }

protected int x;

}

http://www.slideshare.net/IgorShkulipa 12

Вложенные классы

Вложенные классы определяются внутри других классов. Вложенныеклассы имеют доступ ко всем членам содержащего их класса даже кприватным.

public class OuterClass

{

private class InnerClass

{

public InnerClass() { }

}

public OuterClass() { }

}

http://www.slideshare.net/IgorShkulipa 13

Файл Form1.Designer.cs

partial class Form1 {

private System.ComponentModel.IContainer components = null;

protected override void Dispose(bool disposing) {

if (disposing && (components != null)) {

components.Dispose();

}

base.Dispose(disposing); }

private void InitializeComponent(){

this.components = new System.ComponentModel.Container();

this.AutoScaleMode =

System.Windows.Forms.AutoScaleMode.Font;

this.Text = "Form1";

} }

Частичные классы

В C# 1.0 каждый класс объявлялся в отдельном файле. Во второй версиипоявилась возможность объявления частичных классов сиспользованием ключевого слова partial.

Файл Form1.cs

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

}

http://www.slideshare.net/IgorShkulipa 14

Частичные методы

Модификатор partial можно применять не только к классам но и кметодам. Такие методы называются частичными.

Для частичных методов вводятся следующие ограничения:

• Частичные методы должны иметь тип возврата void

• Частичные методы не могут принимать параметров out, нодопускают параметры ref

• Частичные методы не могут быть external

• Частичные методы не могут быть virtual или иметь модификатордоступа, так как они неявно являются приватными

• Частичные методы не могут быть помечены, как static или unsafe

• Частичные методы не могут вызываться делегатами

http://www.slideshare.net/IgorShkulipa 15

Статические классы

В C# 2.0 появилась возможность объявлять классы с модификаторомstatic, что обозначает, что данный класс является набором статическихполей и методов и создавать его экземпляры не разрешено.

public static class StaticClass

{

public static int X {get; set;}

public static int Y {get; set;}

}

http://www.slideshare.net/IgorShkulipa 16

Анонимные типы

С# позволяет вводить анонимные типы используя неявно типизированныепеременные совместно с расширенным синтаксисом оператора new.

class Program

{

static void Main(string[] args)

{

var PersoneName1 = new {Name="Ivan", Surname="Ivanov"};

var PersoneName2 = new { Name = "Petr", Surname = "Petrov" };

Console.WriteLine("{0} {1}\n", PersoneName1.Name, PersoneName1.Surname);

Console.WriteLine("{0} {1}\n", PersoneName2.Name, PersoneName2.Surname);

Console.ReadKey();

}

}

http://www.slideshare.net/IgorShkulipa 17

Упаковка и распаковка

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

Когда тип значения упаковывается средой CLR, она создает программу-оболочку значения внутри System.Object и сохраняет ее вуправляемой куче.

Операция распаковки извлекает тип значения из объекта.Упаковка-преобразование является неявной.Распаковка-преобразование является явной.Концепция упаковки и распаковки лежит в основе единой системы типов

C#, в которой значение любого типа можно рассматривать как объект.

int i = 123;

// Boxing i

object o = i;

o = 321;

// Unboxing i

i = (int)o;

http://www.slideshare.net/IgorShkulipa 18

Создание объектов

Для объявления объекта произвольного типа используется следующаяконструкция:

<тип> имя переменной = new <тип>();

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

new имя_класса {имя поля= выражение, имя поля= выражение, ...}

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

http://www.slideshare.net/IgorShkulipa 19

Конструкторы

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

Если не предоставить конструктор для объекта, C# создаст конструкторпо умолчанию, который создаст экземпляр объекта и задастпеременным-членам значения по умолчанию.

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

Статические конструкторы = конструкторы классаОбычные конструкторы = конструкторы экземпляра

http://www.slideshare.net/IgorShkulipa 20

Статические конструкторы

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

• Статический конструктор не принимает модификаторы доступа и не

имеет параметров.

• Статический конструктор вызывается автоматически для

инициализации класса перед созданием первого экземпляра или

ссылкой на какие-либо статические члены.

• Статический конструктор нельзя вызывать напрямую.

• Пользователь не управляет тем, когда статический конструктор

выполняется в программе.

• Если статический конструктор инициирует исключение, среда

выполнения не вызывает его во второй раз, и тип остается

неинициализированным на время существования приложения.

http://www.slideshare.net/IgorShkulipa 21

Нследование

Синтаксис объявления классов-наследников похож на объявлениенаследников в С++.

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

Следующий код не скомпилируется:

internal class Base

{

public Base()

{ }

protected int x;

}

public class Derived: Base

{

private Derived(Derived arg)

{ this.x = arg.x; }

}

http://www.slideshare.net/IgorShkulipa 22

Ключевые слова base и this

Ключевое слово this используется, как ссылка на текущий экземпляркласса.

Ключевое слово base используется как ссылка на базовый класс.

http://www.slideshare.net/IgorShkulipa 23

Полиморфизм

class Program

{

private static void DrawShape(Shape shape)

{

shape.Draw();

}

static void Main(string[] args)

{

Shape s1 = new Shape();

Shape s2 = new Rectangle();

Shape s3 = new Circle();

DrawShape(s1);

DrawShape(s2);

DrawShape(s3);

Console.ReadKey();

}

}

public class Shape

{

public virtual void Draw()

{

Console.WriteLine("Shape.Draw");

}

}

public class Rectangle : Shape

{

public override void Draw()

{

Console.WriteLine("Rectangle.Draw");

}

}

public class Circle : Shape

{

public override void Draw()

{

Console.WriteLine("Circle.Draw");

}

}

Полиморфизм обеспечиваетсяблагодаря механизму виртуальныхметодов

Shape.DrawRectangle.DrawCircle.Draw

http://www.slideshare.net/IgorShkulipa 24

Виртуальные методы

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

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

Переопределение метода служит основанием для воплощения динамическойдиспетчеризации методов, которая представляет собой механизм разрешениявызова во время выполнения, а не компиляции. Значение динамическойдиспетчеризации методов состоит в том, что именно благодаря ей в С#реализуется динамический полиморфизм.

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

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

http://www.slideshare.net/IgorShkulipa 25

Ключевое слово new

class Program

{

private static void DrawShape(Shape shape)

{

shape.Draw();

}

static void Main(string[] args)

{

Shape s1 = new Shape();

Shape s2 = new Rectangle();

Shape s3 = new Circle();

DrawShape(s1);

DrawShape(s2);

DrawShape(s3);

Console.ReadKey();

}

}

public class Shape

{

public virtual void Draw()

{

Console.WriteLine("Shape.Draw");

}

}

public class Rectangle : Shape

{

public override void Draw()

{

Console.WriteLine("Rectangle.Draw");

}

}

public class Circle : Shape

{

public new void Draw()

{

Console.WriteLine("Circle.Draw");

}

} Shape.DrawRectangle.DrawShape.Draw

http://www.slideshare.net/IgorShkulipa 26

Интерфейсы

Интерфейс – это класс, который не имеет реализации методов. Интерфейсне может содержать статических методов.

По умолчанию используется модификатор доступа public

public interface IBase

{

void Method1();

}

public class Derived : IBase

{

public void Method1()

{

Console.WriteLine("Method 1\n");

}

}

http://www.slideshare.net/IgorShkulipa 27

Реализация интерфейса

Неявная Явная

interface IControl

{

void Paint();

}

interface ISurface

{

void Paint();

}

class SampleClass : IControl,

ISurface

{

public void Paint()

{

Console.WriteLine("Paint");

}

}

public class SampleClass : IControl,

ISurface

{

void IControl.Paint()

{

System.Console.WriteLine("IControl.Paint");

}

void ISurface.Paint()

{

System.Console.WriteLine("ISurface.Paint");

}

}

SampleClass obj = new SampleClass();

obj.Paint(); // Ошибка компиляции

IControl c = (IControl)obj;

c.Paint(); // Вызов IControl.Paint

ISurface s = (ISurface)obj;

s.Paint(); // Вызов ISurface.Paint

http://www.slideshare.net/IgorShkulipa 28

Финализаторы

Финализаторы являются методами для класса, которые выполняютсяперед тем, как сборщик мусора выполнит очистку памяти от объектов,на которые нет ссылок. Синтаксис написания финализаторов включаетв себя имя класса, предваряемое символом “~”

class Class1

{

~Class1() { }

}

Когда сборщик мусора выполняет очистку памяти от объекта, перед этим он вызывает метод Finalize, который является переопределяемым из System.Object. Но перегружать явно этот метод нельзя, для этого используются финализаторы.

http://www.slideshare.net/IgorShkulipa 29

Интерфейс IDisposable

Определяет методы освобождения распределенных ресурсов.

public interface IDisposable

Метод Dispose выполняет определяемые приложением задачи, связанныес освобождением или сбросом неуправляемых ресурсов.

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

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

Метод Dispose этого интерфейса используется вместе со сборщикоммусора для освобождения неуправляемых ресурсов явным образом.Пользователь объекта может вызвать этот метод, когда объект емубольше не нужен.

http://www.slideshare.net/IgorShkulipa 30

Паттерны (шаблоны проектирования)

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

В общем случае паттерн состоит из четырех основных элементов:

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

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

Решение представляет собой описание элементов дизайна, отношений междуними, функций каждого элемента. Конкретный дизайн или реализация неимеются ввиду, поскольку паттерн – это шаблон, применимый в самых разныхситуациях.

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

http://www.slideshare.net/IgorShkulipa 31

Классификация паттернов

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

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

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

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

http://www.slideshare.net/IgorShkulipa 32

Паттерны проектирования

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

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

Структурные - шаблоны проектирования, в которыхрассматривается вопрос о том, как из классов и объектовобразуются более крупные структуры.

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

http://www.slideshare.net/IgorShkulipa 33

Порождающие паттерны

● Singleton (Одиночка) - контролирует создание единственногоэкземпляра некоторого класса и предоставляет доступ к нему.

● Factory Method (Фабричный метод) - В его классическом вариантевводится полиморфный класс Factory, в котором определяетсяинтерфейс фабричного метода, а ответственность за созданиеобъектов конкретных классов переносится на производные от Factoryклассы, в которых этот метод переопределяется.

● Abstract Factory (Абстрактная фабрика) - использует несколькофабричных методов и предназначен для создания целого семействаили группы взаимосвязанных объектов.

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

● Prototype (Прототип) - создает новые объекты с помощьюпрототипов. Прототип - некоторый объект, умеющий создавать позапросу копию самого себя.

● Object Pool (Пул объектов) - используется в случае, когда созданиеобъекта требует больших затрат или может быть создано толькоограниченное количество объектов некоторого класса.

http://www.slideshare.net/IgorShkulipa 34

Структурные шаблоны проектирования

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

◦ Bridge отделяет абстракцию от реализации так, что то и другоеможно изменять независимо.

◦ Composite группирует схожие объекты в древовидные структуры.Рассматривает единообразно простые и сложные объекты.

◦ Decorator используется для расширения функциональностиобъектов. Являясь гибкой альтернативой порождению классов,паттерн Decorator динамически добавляет объекту новыеобязанности.

◦ Facade предоставляет высокоуровневый унифицированныйинтерфейс к набору интерфейсов некоторой подсистемы, чтооблегчает ее использование.

◦ Flyweight использует разделение для эффективной поддержкимножества объектов.

◦ Proxy замещает другой объект для контроля доступа к нему.

http://www.slideshare.net/IgorShkulipa 35

Шаблоны поведения

Паттерн Chain of Responsibility позволяет обработать запроснескольким объектам-получателям. Получатели связываются вцепочку, и запрос передается по цепочке, пока не будет обработанкаким-то объектом. Паттерн Chain of Responsibility позволяет такжеизбежать жесткой зависимости между отправителем запроса и егополучателями.

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

Паттерн Iterator предоставляет механизм обхода элементов составныхобъектов (коллекций) не раскрывая их внутреннего представления.

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

Паттерн Mediator инкапсулирует взаимодействие совокупностиобъектов в отдельный объект-посредник. Уменьшает степеньсвязанности взаимодействующих объектов - им не нужно хранитьссылки друг на друга.

http://www.slideshare.net/IgorShkulipa 36

Шаблоны поведенияПаттерн Memento получает и сохраняет за пределами объекта его

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

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

Паттерн State позволяет объекту изменять свое поведение взависимости от внутреннего состояния. Создается впечатление, чтообъект изменил свой класс. Паттерн State является объектно-ориентированной реализацией конечного автомата.

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

Паттерн Template Method определяет основу алгоритма и позволяетподклассам изменить некоторые шаги этого алгоритма без измененияего общей структуры.

Паттерн Visitor определяет операцию, выполняемую на каждомэлементе из некоторой структуры без изменения классов этихобъектов.

http://www.slideshare.net/IgorShkulipa 37

Шаблон проектирования Singleton

public class Singleton

{

public static Singleton Instance

{

get

{

if (instance == null) instance = new Singleton();

return instance;

}

}

public void Method1() { Console.WriteLine("Singleton.Method1"); }

public void Method2() { Console.WriteLine("Singleton.Method2"); }

private Singleton() { }

private static Singleton instance;

}

class Program

{

static void Main(string[] args)

{

Singleton.Instance.Method1();

Singleton.Instance.Method2();

}

}

http://www.slideshare.net/IgorShkulipa 38

Применение Singleton

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

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

http://www.slideshare.net/IgorShkulipa 39

Лабораторная работа №2. ООП на C#

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

Создать классы-наследники для документов MS Word, PDF, MS Excel, TXT,HTML.

Переопределить методы получения информации о документе.

Создать консольное приложение, использующее класс на основе паттернаSingleton, реализующий меню для вывода информации о документе.