Publicité

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

18 May 2016
Publicité

Contenu connexe

Publicité
Publicité

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

  1. Темы лекции: ООП на C#. Практическое задание: ООП на C#. Тренер: Игорь Шкулипа, к.т.н. Платформа .Net и язык программирования C#. Занятие 2
  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); } }
  3. http://www.slideshare.net/IgorShkulipa 3 Модификаторы доступа Модификатор Значение public Член является общедоступным. Доступ никак не ограничен. protected Член виден классу, в котором он определен и всем классам-наследникам internal Член виден везде в пределах содержащей его сборки. protected internal Является комбинацией protected и internal с операцией «ИЛИ» private Член виден только классу, в котором он определен.
  4. http://www.slideshare.net/IgorShkulipa 4 Модификаторы доступа Модификатор Значение static Член является членом класса, то есть общим для всех экземпляров. readonly Определяет поле, доступное только для чтения. const Константное поле. volatile Указывает компилятору на то, что это поле может быть модифицировано операционной системой или другим потоком.
  5. http://www.slideshare.net/IgorShkulipa 5 Поля и методы Поля (data members) хранят всю необходимую информацию об объекте, формируют его состояние, характеристики и т.п. Методы (methods) – программный код, выполненный в виде функции, реагирующий на передачу объекту определенного сообщения.
  6. 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(); }}
  7. http://www.slideshare.net/IgorShkulipa 7 Свойства Если для свойства определено только средство get, то такое свойство будет доступно только для чтения. Если для свойства определено только средство доступа set, то такое свойство будет доступно только для записи. В С# 3.0 добавлены автореализуемые свойства: class GetSetExample { public int X { get; set; } public int Y { get; set; } } При автореализуемых свойствах компилятор генерирует приватное поле для хранения этой информации.
  8. 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 - аргументы, которые не должны быть явно инициализированы, прежде чем они передаются.
  9. 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); } }
  10. http://www.slideshare.net/IgorShkulipa 10 Герметизированные классы Ключевое слово sealed, примененное к классу указывает на то, что этот класс является герметизированным и наследование от него не разрешается. public sealed class SealedClass : Base { public int X { get { return x; } set { x = value; } } }
  11. http://www.slideshare.net/IgorShkulipa 11 Абстрактные классы Абстрактные классы противоположны герметизированным классам. Иногда возникает необходимость спроектировать класс, который будет служить исключительно базовым классом. Для определения таких классов используется ключевое слово abstract. public abstract class Base { public Base() { } protected int x; }
  12. http://www.slideshare.net/IgorShkulipa 12 Вложенные классы Вложенные классы определяются внутри других классов. Вложенные классы имеют доступ ко всем членам содержащего их класса даже к приватным. public class OuterClass { private class InnerClass { public InnerClass() { } } public OuterClass() { } }
  13. 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(); } }
  14. http://www.slideshare.net/IgorShkulipa 14 Частичные методы Модификатор partial можно применять не только к классам но и к методам. Такие методы называются частичными. Для частичных методов вводятся следующие ограничения: • Частичные методы должны иметь тип возврата void • Частичные методы не могут принимать параметров out, но допускают параметры ref • Частичные методы не могут быть external • Частичные методы не могут быть virtual или иметь модификатор доступа, так как они неявно являются приватными • Частичные методы не могут быть помечены, как static или unsafe • Частичные методы не могут вызываться делегатами
  15. 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;} }
  16. 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(); } }
  17. 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;
  18. http://www.slideshare.net/IgorShkulipa 18 Создание объектов Для объявления объекта произвольного типа используется следующая конструкция: <тип> имя переменной = new <тип>(); Инициализаторы объектов предоставляют способ создания объекта и инициализации его полей и свойств. Если используются инициализаторы объектов, то вместо обычного вызова конструктора класса указываются имена полей или свойств, инициализируемых первоначально задаваемым значением. Следовательно, синтаксис инициализатора объекта предоставляет альтернативу явному вызову конструктора класса. new имя_класса {имя поля= выражение, имя поля= выражение, ...} Использование оператора new для типов-значений необходимо только в том случае, когда должен быть вызван один из конструкторов типа.
  19. http://www.slideshare.net/IgorShkulipa 19 Конструкторы Каждый раз, когда создается класс или структура, вызывается конструктор. Класс или структура может иметь несколько конструкторов, принимающих различные аргументы. Конструкторы позволяют программисту задавать значения по умолчанию, ограничивать число установок и писать код, который является гибким и удобным для чтения. Если не предоставить конструктор для объекта, C# создаст конструктор по умолчанию, который создаст экземпляр объекта и задаст переменным-членам значения по умолчанию. Статический конструктор используется для инициализации любых статических данных или для выполнения определенного действия, которое требуется выполнить только один раз. Он вызывается автоматически перед созданием первого экземпляра или ссылкой на какие-либо статические члены. Статические конструкторы = конструкторы класса Обычные конструкторы = конструкторы экземпляра
  20. http://www.slideshare.net/IgorShkulipa 20 Статические конструкторы Статические конструкторы обладают следующими свойствами. • Статический конструктор не принимает модификаторы доступа и не имеет параметров. • Статический конструктор вызывается автоматически для инициализации класса перед созданием первого экземпляра или ссылкой на какие-либо статические члены. • Статический конструктор нельзя вызывать напрямую. • Пользователь не управляет тем, когда статический конструктор выполняется в программе. • Если статический конструктор инициирует исключение, среда выполнения не вызывает его во второй раз, и тип остается неинициализированным на время существования приложения.
  21. 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; } }
  22. http://www.slideshare.net/IgorShkulipa 22 Ключевые слова base и this Ключевое слово this используется, как ссылка на текущий экземпляр класса. Ключевое слово base используется как ссылка на базовый класс.
  23. 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.Draw Rectangle.Draw Circle.Draw
  24. http://www.slideshare.net/IgorShkulipa 24 Виртуальные методы Метод объявляется как виртуальный в базовом классе с помощью ключевого слова virtual, указываемого перед его именем. Когда виртуальный метод переопределяется в производном классе, то для этого используется модификатор override. А сам процесс повторного определения виртуального метода в производном классе называется переопределением метода. При переопределении имя, возвращаемый тип и сигнатура переопределяющего метода должны быть точно такими же, как и у того виртуального метода, который переопределяется. Кроме того, виртуальный метод не может быть объявлен как static или abstract. Переопределение метода служит основанием для воплощения динамической диспетчеризации методов, которая представляет собой механизм разрешения вызова во время выполнения, а не компиляции. Значение динамической диспетчеризации методов состоит в том, что именно благодаря ей в С# реализуется динамический полиморфизм. Если при наличии многоуровневой иерархии виртуальный метод не переопределяется в производном классе, то выполняется ближайший его вариант, обнаруживаемый вверх по иерархии. В производном классе можно определить член с таким же именем, как и у члена его базового класса. В этом случае член базового класса скрывается в производном классе. Если член базового класса требуется скрыть намеренно, то перед его именем следует указать ключевое слово new.
  25. 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.Draw Rectangle.Draw Shape.Draw
  26. http://www.slideshare.net/IgorShkulipa 26 Интерфейсы Интерфейс – это класс, который не имеет реализации методов. Интерфейс не может содержать статических методов. По умолчанию используется модификатор доступа public public interface IBase { void Method1(); } public class Derived : IBase { public void Method1() { Console.WriteLine("Method 1n"); } }
  27. 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
  28. http://www.slideshare.net/IgorShkulipa 28 Финализаторы Финализаторы являются методами для класса, которые выполняются перед тем, как сборщик мусора выполнит очистку памяти от объектов, на которые нет ссылок. Синтаксис написания финализаторов включает в себя имя класса, предваряемое символом “~” class Class1 { ~Class1() { } } Когда сборщик мусора выполняет очистку памяти от объекта, перед этим он вызывает метод Finalize, который является переопределяемым из System.Object. Но перегружать явно этот метод нельзя, для этого используются финализаторы.
  29. http://www.slideshare.net/IgorShkulipa 29 Интерфейс IDisposable Определяет методы освобождения распределенных ресурсов. public interface IDisposable Метод Dispose выполняет определяемые приложением задачи, связанные с освобождением или сбросом неуправляемых ресурсов. Основное назначение этого интерфейса заключается в освобождении неуправляемых ресурсов. Сборщик мусора автоматически освобождает память, выделенную для управляемого объекта, если этот объект уже не используется. Однако он не может предсказать момент выполнения сбора мусора. Кроме того, у сборщика мусора нет сведений о неуправляемых ресурсах, таких как дескрипторы окон, или открытые файлы и потоки. Метод Dispose этого интерфейса используется вместе со сборщиком мусора для освобождения неуправляемых ресурсов явным образом. Пользователь объекта может вызвать этот метод, когда объект ему больше не нужен.
  30. http://www.slideshare.net/IgorShkulipa 30 Паттерны (шаблоны проектирования) Паттерн описывает задачу, которая снова и снова возникает в работе, а так же принцип ее решения, причем таким образом, что это решение можно потом использовать много раз, ничего не изобретая заново. В общем случае паттерн состоит из четырех основных элементов: Имя. Присваивание паттернам имен позволяет проектировать на более высоком уровне абстракции. С помощью имен паттернов можно вести общение с коллегами. Назначение паттернам имен упрощает общение в профессиональной среде. Задача - это описание того, когда следует применять паттерн. Необходимо сформулировать задачу и ее контекст. Может описываться конкретная проблема проектирования, например способ представления алгоритмов в виде объектов. Так же задача может включать перечень условий, при выполнении которых имеет смысл применять данный паттерн. Решение представляет собой описание элементов дизайна, отношений между ними, функций каждого элемента. Конкретный дизайн или реализация не имеются ввиду, поскольку паттерн – это шаблон, применимый в самых разных ситуациях. Результаты - это следствия применения паттерна и разного рода компромиссы. Хотя при описании проектных решений о последствиях часто не упоминают, знать о них необходимо, чтобы можно было выбрать между различными вариантами и оценить преимущества и недостатки данного паттерна.
  31. http://www.slideshare.net/IgorShkulipa 31 Классификация паттернов Паттерны проектирования программных систем делятся на следующие категории: Архитектурные паттерны. Описывают структурную схему программной системы в целом. В данной схеме указываются отдельные функциональные составляющие системы, называемые подсистемами, а также взаимоотношения между ними. Паттерны проектирования. описывают схемы детализации программных подсистем и отношений между ними, при этом они не влияют на структуру программной системы в целом и сохраняют независимость от реализации языка программирования. Идиомы - низкоуровневые паттерны, имеют дело с вопросами реализации какой-либо проблемы с учетом особенностей данного языка программирования.
  32. http://www.slideshare.net/IgorShkulipa 32 Паттерны проектирования Паттерны проектирования делятся на следующие категории: Порождающие - шаблоны проектирования, которые абстрагируют процесс создания объектов. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Структурные - шаблоны проектирования, в которых рассматривается вопрос о том, как из классов и объектов образуются более крупные структуры. Поведенческие - шаблоны проектирования, определяющие алгоритмы и способы реализации взаимодействия различных объектов и классов.
  33. http://www.slideshare.net/IgorShkulipa 33 Порождающие паттерны ● Singleton (Одиночка) - контролирует создание единственного экземпляра некоторого класса и предоставляет доступ к нему. ● Factory Method (Фабричный метод) - В его классическом варианте вводится полиморфный класс Factory, в котором определяется интерфейс фабричного метода, а ответственность за создание объектов конкретных классов переносится на производные от Factory классы, в которых этот метод переопределяется. ● Abstract Factory (Абстрактная фабрика) - использует несколько фабричных методов и предназначен для создания целого семейства или группы взаимосвязанных объектов. ● Builder (Строитель) - определяет процесс поэтапного конструирования сложного объекта, в результате которого могут получаться разные представления этого объекта. ● Prototype (Прототип) - создает новые объекты с помощью прототипов. Прототип - некоторый объект, умеющий создавать по запросу копию самого себя. ● Object Pool (Пул объектов) - используется в случае, когда создание объекта требует больших затрат или может быть создано только ограниченное количество объектов некоторого класса.
  34. http://www.slideshare.net/IgorShkulipa 34 Структурные шаблоны проектирования ◦ Adapter представляет собой программную обертку над уже существующими классами и предназначен для преобразования их интерфейсов к виду, пригодному для последующего использования в новом программном проекте. ◦ Bridge отделяет абстракцию от реализации так, что то и другое можно изменять независимо. ◦ Composite группирует схожие объекты в древовидные структуры. Рассматривает единообразно простые и сложные объекты. ◦ Decorator используется для расширения функциональности объектов. Являясь гибкой альтернативой порождению классов, паттерн Decorator динамически добавляет объекту новые обязанности. ◦ Facade предоставляет высокоуровневый унифицированный интерфейс к набору интерфейсов некоторой подсистемы, что облегчает ее использование. ◦ Flyweight использует разделение для эффективной поддержки множества объектов. ◦ Proxy замещает другой объект для контроля доступа к нему.
  35. http://www.slideshare.net/IgorShkulipa 35 Шаблоны поведения Паттерн Chain of Responsibility позволяет обработать запрос нескольким объектам-получателям. Получатели связываются в цепочку, и запрос передается по цепочке, пока не будет обработан каким-то объектом. Паттерн Chain of Responsibility позволяет также избежать жесткой зависимости между отправителем запроса и его получателями. Паттерн Command преобразовывает запрос на выполнение действия в отдельный объект-команду. Это придает системе гибкость: позволяет осуществлять динамическую замену команд, использовать сложные составные команды, осуществлять отмену операций. Паттерн Iterator предоставляет механизм обхода элементов составных объектов (коллекций) не раскрывая их внутреннего представления. Паттерн Interpreter предназначен для решения повторяющихся задач, которые можно описать некоторым языком. Для этого паттерн Interpreter описывает решаемую задачу в виде предложений этого языка, а затем интерпретирует их. Паттерн Mediator инкапсулирует взаимодействие совокупности объектов в отдельный объект-посредник. Уменьшает степень связанности взаимодействующих объектов - им не нужно хранить ссылки друг на друга.
  36. http://www.slideshare.net/IgorShkulipa 36 Шаблоны поведения Паттерн Memento получает и сохраняет за пределами объекта его внутреннее состояние так, чтобы позже можно было восстановить объект в таком же состоянии. Паттерн Observer определяет зависимость "один-ко-многим" между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются и обновляются автоматически. Паттерн State позволяет объекту изменять свое поведение в зависимости от внутреннего состояния. Создается впечатление, что объект изменил свой класс. Паттерн State является объектно- ориентированной реализацией конечного автомата. Если поведение системы настраивается согласно одному из некоторого множества алгоритму, то применение паттерна Strategy переносит семейство алгоритмов в отдельную иерархию классов, что позволяет заменять один алгоритм другим в ходе выполнения программы. Кроме того, такую систему проще расширять и поддерживать. Паттерн Template Method определяет основу алгоритма и позволяет подклассам изменить некоторые шаги этого алгоритма без изменения его общей структуры. Паттерн Visitor определяет операцию, выполняемую на каждом элементе из некоторой структуры без изменения классов этих объектов.
  37. 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(); } }
  38. http://www.slideshare.net/IgorShkulipa 38 Применение Singleton Применяется, когда нужен только один экземпляр класса. Например для хранения глобальной конфигурации системы, для ведения логов, связи с базой данных и т.д. Основное преимущество перед глобальными переменными в том, что экземпляр класса создается не при инициализации программы, а по первому требованию.
  39. http://www.slideshare.net/IgorShkulipa 39 Лабораторная работа №2. ООП на C# Создать класс для хранения информации об электронном документе (имя, автор, ключевые слова, тематика, путь к файлу). Создать классы-наследники для документов MS Word, PDF, MS Excel, TXT, HTML. Переопределить методы получения информации о документе. Создать консольное приложение, использующее класс на основе паттерна Singleton, реализующий меню для вывода информации о документе.
Publicité