Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Объектно-ориентированное проектирование и программирование↑ Стр 1 из 4Следующая ⇒ Содержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Лабораторная 3 Объектно-ориентированное проектирование и программирование Задание состоит из описания базового класса и его потомков. Индивидуальные варианты
Объектное проектирование: Разработать диаграммы UML трех видов: 1. Диаграммы сценариев (Use Case) 2. Диаграммы классов (Classes) 3. Диаграммы последовательности (Sequence) Объектное программирование: Разработать все классы иерархии и Windows – приложение для добавления, ввода по 2 объекта каждого класса, просмотра всех объектов, выдачи запроса, записи объектов в файл и чтения их из файла Объектно-ориентированное проектирование Виды диаграмм UML 1.5 определял двенадцать типов диаграмм, разделенных на три группы: · четыре типа диаграмм представляют статическую структуру приложения; · пять представляют поведенческие аспекты системы; · три представляют физические аспекты функционирования системы (диаграммы реализации). Перечислим названия наиболее употребимых диаграмм: · диаграмма прецедентов; · диаграмма классов; · диаграмма объектов; · диаграмма последовательностей; · диаграмма взаимодействия; · диаграмма состояний; · диаграмма активности; · диаграмма развертывания. В дальнейшем рассматриваются только три их них. Можно предложить такую последовательность построения диаграмм: · диаграмма прецедентов, · диаграмма классов, · диаграмма последовательностей,
Диаграммы классов Класс (class) - категория вещей, которые имеют общие атрибуты и операции. Классы - это строительные блоки любой объектно-ориентированной системы. Они представляют собой описание совокупности объектов с общими атрибутами, операциями. При проектировании объектно-ориентированных систем диаграммы классов обязательны. Классы используются в процессе анализа предметной области для составления словаря предметной области разрабатываемой системы. Это могут быть как понятия предметной области, так и классы, из которых строится программная система и которые описывают программные сущности. Диаграмма классов - это набор статических, декларативных элементов модели. Класс на диаграмме изображается в виде прямоугольника, разделенного горизонтальными линиями на три части. В первой части указывается название класса. Вторая часть содержит перечень атрибутов класса, которые характеризуют тот или иной объект этого класса в модели предметной области. Третья часть содержит перечень операций, отражающих его поведение в модели предметной области. Пользователю о внутреннем устройстве классов знать не нужно. Сокрытие от пользователя внутреннего устройства объектов называется инкапсуляцией. Иначе говоря, инкапсуляция - это защита отдельных элементов объекта, не затрагивающих существенных характеристик его как целого. Пример диаграммы классов иллюстрирует "генеалогическое древо" бытовой техники с помощью операции наследования (рис.). Рис. Иерархия классов предметной области Нужно создавать классы на основе уже существующих, пользуясь понятием наследования, которое играет очень важную роль в объектно-ориентированном проектировании (ООП), являясь одним из его базовых принципов. Наследование- это отношение между более общей сущностью, называемой суперклассом, и ее конкретным воплощением, называемым подклассом. Иногда наследование называют отношением типа "является", имея в виду, что одни сущности (например, круг, квадрат, треугольник) являются воплощением более общей сущности (например, класса "геометрическая фигура"). При этом все атрибуты и операции суперкласса входят в состав подкласса. Наследование на диаграммах обозначается незакрашенной треугольной стрелкой, направленной на суперкласс. Пример наследования классов с атрибутами (рис.). Рис. Наследование классов
На первый взгляд, кажется странным, что класс "точка" не имеет никаких атрибутов, а круг имеет только радиус. С прямоугольником, вроде бы, все понятно - ширина и высота вот только где прямоугольник расположен на плоскости? Положение всех трех фигур можно однозначно определить с помощью пары чисел. Для точки - это вообще единственные ее характеристики, для круга и прямоугольника - их центры. Таким образом, мы создали суперкласс "Фигура", имеющий два атрибута - координаты центра. Все остальные классы на этой диаграмме связаны с классом "Фигура" отношением наследования, то есть в них нужно доопределить только "недостающие" атрибуты - радиус, ширину и высоту. Атрибуты, описывающие координаты центра, эти классы имеют изначально как потомки класса "Фигура" - они их наследуют. Объекты разных классов могут поддерживать один и тот же набор операций именно так, как того ожидает пользователь. Примером тому может служить рассмотренная выше диаграмма с геометрическими фигурами. Все рассмотренные фигуры имеют, например, операцию рисования на экране. С точки зрения пользователя в каждом случае это одно и то же действие. Однако реализованы эти операции по-разному - ведь процедура изображения прямоугольника сильно отличается от подобной процедуры для круга. Но для пользователя это неважно: ведь имя операции одно и то же! А возможно это благодаря еще одному из основных принципов ООП - полиморфизму. Работа механизма полиморфизма основана на совпадении имени операции в разных классах. Операции внутри классов-потомков могут быть (и наверняка будут) переопределены, их реализации будут различными, а имена останутся неизменными. Таким образом (и в этом легко ощутить мощь ООП), выполняя одни и те же операции, разные объекты могут вести себя по-разному. Как только пользователь обращается к некоторой операции, определяется фактический класс объекта и вызывается соответствующая операция класса. Инкапсуляция, наследование и полиморфизм являются теми самыми тремя китами, на которых держится ООП. В составе пакета C# имеется средство просмотра диаграммы классов на языке UML Пакет – это совокупность нескольких взаимосвязанных классов. В окне Main группы Logical View будем изображать два пакета: пакет данных и пакет элементов программ: Для каждого пакета создается новая диаграмма с изображениями взаимосвязанных классов. Пакет данных – это классы иерархии индивидуального задания. Пакет элементов программ – это классы Меню (как правило, одно), Формы входных документов и Отчеты выходных документов, создаваемые при разработке пакета. Пиктограмма класса – это прямоугольник из трех частей (имя класса, необязательный список атрибутов с типами и список операций). Атрибуты класса пакета программ – это атрибуты класса согласно индивидуальному заданию, а его операции – конструкторы, а также метод info(). Атрибуты класса из пакета элементов программ – это поля, видимые на форме, а операции соответствуют кнопкам формы Между классами нужно изобразить связи.
Как свойства класса Класс имеет три важных свойства: инкапсуляция, наследование и полиморфизм. Инкапсуляция связана с областями видимости членов класса. Будем понимать под инкапсуляцией доступность объекта исключительно посредством его свойств и методов. Другими словами, концепция инкапсуляции призвана обеспечивать безопасность проектирования и реализации программы на основе локализации манипулирования объектом в областях его полей и методов. Иначе говоря, полями объекта возможно оперировать исключительно посредством его методов. Практическая важность концепции инкапсуляции для языка C#) определяется следующими фундаментальными свойствами. Прежде всего, реализация концепции инкапсуляции обеспечивает совместное хранение данных (полей) и функций (методов) внутри объекта. Наследование (inheritance) является одним из самых важных механизмов в ООП. Любой класс может наследоваться от другого класса, а это значит, что он будет иметь все те же члены, что и класс, от которого он унаследован. В терминологии ООП класс, от которого наследуется другой класс (или, другими словами, создается производный класс), называется родительским или базовым классом. Важно обратить внимание на то, что в С# напрямую наследоваться классы могут только от одного базового класса, хотя у базового класса может быть свой собственный базовый класс и т.д. Механизм наследования позволяет расширять или создавать специфические классы от одного более общего базового класса. Например, возьмем класс, представляющий животное с фермы. Этот класс мог бы называться Animal и обладать методами вроде EatFood () (Кормить) или Breed () (Разводить). Можно создать производный класс по имени Cow (Корова), который бы поддерживал все те же самые методы, но при этом также имел и свои собственные, например, Моо() (Мычать) и SupplyMilk() (Давать молоко), а также еще один производный класс по имени Chicken (Курица) с методами Cluck() (Кудахтать) и LayEgg() (Снести яйцо). При применении наследования от базового класса важным становится вопрос о доступности членов. Закрытые члены базового класса не являются доступными для производного класса, а открытые — являются. Однако открытые члены доступны как для производного класса, так и для внешнего кода. Поэтому если бы использовать можно было только два таких уровня доступности, создание члена, доступного как для базового, так и для производного класса, но не для внешнего кода, оказалось бы невозможным. Для исключения вероятности возникновения подобной проблемы существует еще и третий уровень доступности — protected, при котором доступ к члену имеют только производные классы. Что касается внешнего кода, то для него член с уровнем доступности protected идентичен члену с уровнем private. Помимо уровня защиты для члена еще также может определяться и поведение, связанное с наследованием. Члены базового класса могут быть виртуальными (virtual), а это означает то, что они могут переопределяться в классе, который их наследует. Другими словами, в производном классе для членов может предоставляться альтернативная реализация. Если никакой альтернативной реализации не предоставлено, тогда любой внешний код, получающий доступ к члену через производный класс, автоматически использует реализацию этого члена, которая содержится в базовом классе. Виртуальные члены не могут быть закрытыми, поскольку это приводит к парадоксу: нельзя говорить, что член может переопределяться в производном классе и одновременно утверждать, что он не должен быть доступен в производном классе. В примере с классом Animal можно было бы сделать виртуальным метод EatFood () и предоставить для него новую реализацию в каком-то производном классе, например, в Cow. Одним из результатов наследования является наличие в классах, унаследованных от базового, некоторых общих возможностей с ним (полей и методов). Благодаря этому зачастую оказывается возможным применять для объектов, которые как экземпляры классов с общим базовым типом, имеют идентичный синтаксис. Например, при наличии у класса Animal метода по имени EatFood () синтаксис для вызова этого метода из объектов производных классов Cow и Chicken будет выглядеть одинаково: Cow myCow = new Cow(); Chicken myChicken = new Chicken (); myCow.EatFood(); myChicken.EatFood(); Полиморфизм (polymorphism) позволяет присваивать переменной базового типа переменную одного из производных типов, как показано ниже: AnimalmyAnimal = myCow; Никакого приведения типов выполнять не требуется. Далее можно просто вызывать методы базового класса через эту переменную: myAnimal.EatFood(); Данная строка кода приведет к вызову реализации метода EatFood (), содержащейся в производном классе. Важно обратить внимание на то, что вызывать подобным образом методы, определенные в производном классе, нельзя. То есть следующий код работать не будет: myAnimal.Moo (); Однако приводить переменную типа базового класса к переменной типа производного класса и вызывать метод производного класса показанным ниже образом можно: Cow myNewCow = (Cow)myAnimal; myNewCow.Moo(); Полиморфизм является чрезвычайно полезной технологией для решения задач с использованием минимального количества кода в разных объектах - потомках от одного единственного класса. Следует отметить, что полиморфизм может применяться не только в отношении классов, имеющих одинаковый родительский класс. Он точно так же может применяться и, скажем, в отношении дочерних и "внучатых" классов, главное, чтобы в их иерархии наследования присутствовал какой-то общий класс. Пример программирования классов Рассмотрим программирование классов на примере. Пусть имеется базовый класс stud (Студент) и класс-потомок grad_stud (Студент-выпускник). Диаграмма классов имеет вид (рис.) Рис. Диаграмма классов примера
Эту диаграмму можно увидеть в VisualStudio. Поля базового класса: name (Имя), age (Возраст), ball (Балл), group (Группа). У класса-потомка дополнительно есть поле place (Место распределения). Каждому полю соответствует общедоступное свойство. Метод info(), который присутствует в каждом классе, возвращает информацию о полях класса в виде строки, но работает в каждом классе по-своему, так как в каждом классе неодинаковый набор полей. Поэтому этот метод будет виртуальным. Особо нужно сказать о методах, имена которых совпадают с именами классов. Базовая инициализация объекта осуществляется автоматически. Однако иногда бывает необходимо, чтобы на стадии инициализации объекта выполнялись какие-то дополнительные задачи, например, инициализация хранимых объектом данных. Для осуществления подобного применяется функция-конструктор. Все объекты имеют конструктор по умолчанию, который представляет собой не принимающий параметров метод с таким же именем, как у самого класса. Определение класса может также включать несколько методов-конструкторов, принимающих параметры и отличных от конструктора по умолчанию. Такие конструкторы позволяют создавать экземпляр объекта различными способами, например, предоставляя начальные значения для хранимых в объекте данных. В языке С# конструкторы вызываются с использованием ключевого слова new. Например, создать экземпляр объекта CupOfCoffee с применением конструктора по умолчанию можно было бы следующим образом: CupOfCoffeemyCup = newCupOfCoffee (); Экземпляры объектов могут также создаваться и с помощью конструкторов не по умолчанию. Например, у класса CupOfCoffee мог бы существовать конструктор не по умолчанию, принимающий параметр для установки во время создания экземпляра типа кофейных зерен: CupOfCoffeemyCup = new CupOfCoffee("Blue Mountain"); Деструкторы используются для выполнения очистки после удаления объектов. В целом предоставлять код для метода-деструктора не требуется; это делается автоматически. Описание классов примера: public class stud { private string name; privateint age; privateint ball; privateint group; public string Name { get { return name; } set { name = value; } } publicint Group { get { return group; } set { if (value>0&&value<50) group = value; } } publicint Age { get { return age; } set { if (value > 0 && value < 80) age = value; } } publicint Ball { get { return ball; } set { if (value > 0 && value < 100) ball = value; } } public stud(){} public stud (string aname, int aage, int aball,int agr) {Name=aname;Age=aage;Ball=aball;Group=agr;} public virtual string info() { string X; X = Name + " " + Convert.ToString(Age) + " " + Convert.ToString(Ball) + " " + Convert.ToString(Group); return X; } } public class grad_stud: stud { private string place; public string Place { get { return place; } set { place = value; } } public grad_stud(){} public grad_stud (string aname, int aage, int aball, int agr, string aplace): base(aname, aage, aball, agr) { Place = aplace; } public override string info() { string X; X = base.info() + " " + Place; return X; } } Описание класса начинается словом class. В описании класса-потомка grad_stud после двоеточия указывается имя класса-предка. Конструктор класса-потомка после двоеточия содержит вызов конструктора класса-предка (слово base), а в теле метода – инициализацию собственного поля. Метод info() предка содержит слово virtual, которое означает, что этот метод будет переопределен в потомке. Метод info() потомка содержит слово override, которое означает, что этот метод переопределяет одноименный метод предка; метод вначале вызывает одноименный метод предка, а затем присоединяет собственное поле. В языке С# предусмотрен один общий базовый класс для всех объектов, имеющий имя object. Его метод GetType() может быть полезен при использовании полиморфизма, поскольку позволяет выполнять различные операции с объектами в зависимости от их типа, а не одну и ту же операцию для всех объектов, как это часто бывает. Например, при наличии функции, принимающей параметр типа object (это означает, что ей можно передавать практически все что угодно), можно было бы сделать так, чтобы в случае обнаружения объектов определенного типа выполнялись дополнительные задачи. В частности, с использованием комбинации из метода GetType и операции typeof (которая представляет собой операцию С#, преобразующую имя класса в объект System.Type) можно было бы обеспечить выполнение операции сравнения, как показано ниже: if (myObj.GetType () == typeof(MyComplexClass)) {// myObjявляетсяэкземпляромклассаMyComplexClass. } Пример приложения, использующего классы Рассмотрим приложение, основанное на рассмотренной иерархии классов. В приложение поместим главную форму, форму добавления экземпляров классов, форму просмотра всех экземпляров классов и форму запроса. На главной форме поместим меню (рис.): Рис. Главная форма приложения Кроме двух классов иерархии, создадим класс Global для размещения полей, видимых всем формам: class Global { public struct st { public string name, place; public int age, ball, group; }; public static st st1; public static stud A1=new stud(); public static stud A2 = new stud(); public static grad_stud B1=new grad_stud(); public static grad_stud B2 = new grad_stud(); public static FileStream aFile; public static StreamWriter sw; public static StreamReader sr; } Форма добавления (рис.) Рис. Форма добавления студента На форме есть компонента groupBox, содержащая две компоненты radioButton для выбора типа добавляемого объекта, при выполнении события radioButton1_CheckedChanged поля, связанные с местом распределения, становятся невидимы; для аналогичного события для второй кнопки они становятся видимыми: private void radioButton1_CheckedChanged(object sender, EventArgs e) { label5.Visible = false; textBox1.Visible = false; } private void radioButton2_CheckedChanged(object sender, EventArgs e) { label5.Visible = true; textBox1.Visible = true; } После заполнения необходимых полей в зависимости от нажатой кнопки создается и инициализируется определенный экземпляр определенного класса, например, при нажатии кнопки «Первый студент» выполняется код: private void button5_Click(object sender, EventArgs e) {Global.st1.name=textBox2.Text; Global.st1.age = Convert.ToInt32(maskedTextBox1.Text); Global.st1.ball = Convert.ToInt32(maskedTextBox2.Text); Global.st1.group = Convert.ToInt32(maskedTextBox3.Text); Global.A1 = new stud(Global.st1.name, Global.st1.age, Global.st1.ball, Global.st1.group); } Заполняются поля структуры и инициализируктся экземпляр Global.A1. Форма просмотра содержит компоненту ListBox; при загрузке формы выполняется код для добавления в список значений метода Info() для каждого объекта: private void Form3_Load(object sender, EventArgs e) { listBox1.Items.Clear(); if (Global.A1!=null) listBox1.Items.Add(Global.A1.info()); if (Global.A2!=null)listBox1.Items.Add(Global.A2.info()); if (Global.B1!=null)listBox1.Items.Add(Global.B1.info()); if (Global.B2!=null)listBox1.Items.Add(Global.B2.info()); }
Форма запроса имеет вид (рис.): Рис. Форма просмотра При нажатии кнопки выполняется код: private void button1_Click(object sender, EventArgs e) {int cnt=0; if (Global.B1.get_place() == textBox1.Text) cnt++; if (Global.B2.get_place() == textBox1.Text) cnt++; MessageBox.Show(Convert.ToString(cnt)); Close(); } Код записи объектов в файл: Global.aFile = new FileStream("stud.txt", FileMode.Create); Global.sw = new StreamWriter(Global.aFile); Global.sw.Close(); Global.aFile = new FileStream("stud.txt", FileMode.Append); Global.sw = new StreamWriter(Global.aFile); // Записатьданныевфайл
Global.sw.WriteLine("{0},{1},{2},{3},{4}", Global.A1.GetType(), Global.A1.Name, Global.A1.Age, Global.A1.Ball,Global.A1.Group); Global.sw.WriteLine("{0},{1},{2},{3},{4}", Global.A2.GetType(), Global.A2.Name, Global.A2.Age, Global.A2.Ball, Global.A2.Group); Global.sw.WriteLine("{0},{1},{2},{3},{4},{5}", Global.B1.GetType(), Global.B1.Name, Global.B1.Age, Global.B1.Ball, Global.B1.Group,Global.B1.Place); Global.sw.WriteLine("{0},{1},{2},{3},{4},{5}", Global.B2.GetType(), Global.B2.Name, Global.B2.Age, Global.B2.Ball, Global.B2.Group,Global.B2.Place); Global.sw.Close(); Код чтения объектов из файла: stringlin,ob; char[] separator = new char[] { ',' }; string[] slov = new string[6]; Global.aFile = new FileStream("stud.txt", FileMode.Open); Global.sr = new StreamReader(Global.aFile); Global.A1 = new stud(); Global.A2 = new stud(); Global.B1 = new grad_stud(); Global.B2 = new grad_stud();
lin = Global.sr.ReadLine(); slov = lin.Split(separator); ob=slov[0]; if (ob == ("WindowsFormsApplication2.stud")) {Global.A1.Name=slov[1]; Global.A1.Age=Convert.ToInt32(slov[2]); Global.A1.Ball=Convert.ToInt32(slov[3]); Global.A1.Group=Convert.ToInt32(slov[4]); } lin = Global.sr.ReadLine(); slov = lin.Split(separator); Global.A2.Name=slov[1]; Global.A2.Age=Convert.ToInt32(slov[2]); Global.A2.Ball=Convert.ToInt32(slov[3]); Global.A2.Group=Convert.ToInt32(slov[4]); lin = Global.sr.ReadLine(); slov = lin.Split(separator); Global.B1.Name=slov[1]; Global.B1.Age=Convert.ToInt32(slov[2]); Global.B1.Ball=Convert.ToInt32(slov[3]); Global.B1.Group=Convert.ToInt32(slov[4]); Global.B1.Place=slov[5]; lin = Global.sr.ReadLine(); slov = lin.Split(separator); Global.B2.Name=slov[1]; Global.B2.Age=Convert.ToInt32(slov[2]); Global.B2.Ball=Convert.ToInt32(slov[3]); Global.B2.Group=Convert.ToInt32(slov[4]); Global.B2.Place=slov[5]; Global.sr.Close();
Лабораторная 3 Объектно-ориентированное проектирование и программирование Задание состоит из описания базового класса и его потомков. Индивидуальные варианты
Объектное проектирование: Разработать диаграммы UML трех видов: 1. Диаграммы сценариев (Use Case) 2. Диаграммы классов (Classes) 3. Диаграммы последовательности (Sequence) Объектное программирование: Разработать все классы иерархии и Windows – приложение для добавления, ввода по 2 объекта каждого класса, просмотра всех объектов, выдачи запроса, записи объектов в файл и чтения их из файла
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-09-19; просмотров: 528; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.22.66.140 (0.019 с.) |