Первый слайд презентации: Объектно-ориентированное программирование. Языки C++ и C#
1 Объектно-ориентированное программирование. Языки C++ и C# § 46. Что такое ООП? § 47. Объекты и классы § 48. Создание объектов в программе § 49. Скрытие внутреннего устройства § 50. Иерархия классов § 51. Программы с графическим интерфейсом § 52. Программирование в RAD- средах § 53. Использование компонентов § 54. Совершенствование компонентов § 55. Модель и представление
§ 46. Что такое ООП? 2 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 3: Зачем нужно что-то новое?
3 Главная проблема – сложность ! ! программы из миллионов строк тысячи переменных и массивов Э. Дейкстра : «Человечество еще в древности придумало способ управления сложными системами: « разделяй и властвуй »». подзадача 1 подзадача 3 подзадача 2.1 подзадача 2. 2 подзадача 2. 3 подзадача 2 задача Структурное программирование : декомпозиция по задачам человек мыслит иначе, объектами
Слайд 4: Как мы воспринимаем объекты?
4 существенные свойства Абстракция – это выделение существенных свойств объекта, отличающих его от других объектов. Разные цели – разные модели ! !
Слайд 5: Использование объектов
5 Программа – множество объектов (моделей), каждый из которых обладает своими свойствами и поведением, но его внутреннее устройство скрыто от других объектов. Нужно «разделить» задачу на объекты! ! А Б Б1 Б2 Б3 В В1 В2 В3 Г Г1 Г2 декомпозиция по объектам
Слайд 6: Объектно-ориентированное программирование. Языки C++ и C#
§ 47. Объекты и классы 6 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 7: С чего начать?
7 Объектно-ориентированный анализ (ООА): выделить объекты определить их существенные свойства описать поведение (команды, которые они могут выполнять) Что такое объект? ? Объектом можно назвать то, что имеет чёткие границы и обладает состоянием и поведением. Состояние определяет поведение: лежачий человек не прыгнет незаряженное ружье не выстрелит Класс – это множество объектов, имеющих общую структуру и общее поведение.
Слайд 8: Модель дороги с автомобилями
8 Объект «Дорога»: длина ширина (число полос) Дорога длина ширина методы (поведение) свойства (состояние) название класса
Слайд 9: Модель дороги с автомобилями
9 Объект «Машина»: свойства: координаты и скорость все машины одинаковы скорость постоянна на каждой полосе – одна машина если машина выходит за правую границу дороги, вместо нее слева появляется новая машина X P V Машина X ( координата ) P ( полоса ) V ( скорость ) двигаться Метод – это процедура или функция, принадлежащая классу объектов.
Слайд 10: Модель дороги с автомобилями
10 Взаимодействие объектов: Машина X ( координата ) P ( полоса ) V ( скорость ) двигаться Дорога длина ширина узнать длину свойства объектов методы : операции, которые они могут выполнять связи (обмен данными) между объектами Схема определяет Ни слова о внутреннем устройстве объектов! !
Слайд 11: Объектно-ориентированное программирование. Языки C++ и C#
§ 48. Создание объектов в программе 11 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 12: Классы
12 программа – множество взаимодействующих объектов любой объект – экземпляр какого-то класса класс – описание группы объектов с общей структурой и поведением Класс Данные Методы отличие от структур! состояние поведение Поле – это переменная, принадлежащая объекту.
Слайд 13: Класс «Дорога»
13 class TRoad { float Length; int Width; }; Объявление класса : Объявление переменной (создание объекта) : Память не выделяется! ! TRoad road; road. Length = 60 ; road. Width = 3 ; Попытка изменить данные : По умолчанию все члены класса закрытые! ! private ошибка
Слайд 14: Класс «Дорога»
14 class TRoad { public : float Length; int Width; }; Объявление класса : main () { TRoad road; road.Length = 60 ; // работает! road.Width = 3 ; // работает! } Основная программа : public : Общедоступные данные! !
Слайд 15: Класс «Дорога»
15 Конструктор – это метод класса, который вызывается для создания объекта этого класса. TRoad road; вызов конструктора Конструктор по умолчанию строится автоматически! ! Что записано в полях? ? road.Length = ??? road.Width = ??? «мусор»
Слайд 16: Новый конструктор
16 class TRoad { public : float Length ; int Width ; TRoad (); // объявление конструктора }; Класс : TRoad (); TRoad :: TRoad () { Length = 0 ; Width = 0 ; } Конструктор : TRoad :: aaa () { ... } метод aaa класса TRoad Имя конструктора совпадает с именем класса! !
Слайд 17: Конструктор с параметрами
17 class TRoad { public : ... TRoad ( float length0, int width0 ); }; TRoad::TRoad ( float length0, int width0 ) { L ength = length0; W idth = width0; } Конструктор : Вызов : TRoad road ( 60, 3 );
Слайд 18: Защита от неверных данных
18 TRoad::TRoad ( float length0, int width0 ) { if ( length0 > 0 ) L ength = length0; else Length = 1 ; if ( width0 > 0 ) W idth = width0; else W idth = 1 ; }
Слайд 19: Значения параметров по умолчанию
19 class TRoad { public : ... TRoad ( float length0, int width0 = 3 ); }; Вызов : TRoad road ( 60 ); = 3 значение по умолчанию последние в списке параметров width = 3
Слайд 20: Класс «Машина»
20 class TCar { public : float X, V; int P; TRoad *Road; void move(); TCar (); // конструктор без параметров TCar ( TRoad *road0, int p0, float v0 ); }; дорога, по которой едет координата, скорость полоса
Слайд 21: Конструкторы класса «Машина»
21 TCar::TCar () { Road = NULL ; P = 0 ; V = 0 ; X = 0 ; } защита от ошибок – самостоятельно TCar::TCar ( TRoad *road0, int p0, float v0 ) { Road = road0; P = p0; V = v0; X = 0 ; }
Слайд 22: Класс «Машина»: метод move
22 void TCar::move() { X = X + V; if ( X > Road->Length ) X = 0 ; } Равномерное движение : перемещение за одну единицу времени интервал дискретизации выезжает с другой стороны обращение через указатель
Слайд 23: Основная программа
23 const int N = 3 ; TCar cars[N]; int i; for ( i = 0 ; i < N; i++ ) { cars[i].Road = &road; cars[i].P = i + 1 ; cars[i].V = 2.0 *(i + 1 ); } do { for ( i = 0 ; i < N; i++ ) cars[i].move(); } while ( !kbhit() ); пока не нажата (любая) клавиша #include <conio.h>
Слайд 24: Использование указателей
24 const int N = 3 ; TCar * cars[N]; for ( i = 0 ; i < N; i ++ ) cars[i] = new TCar ( &road, i+ 1, 2.0 *(i+ 1 ) ); for ( i = 0 ; i < N; i ++ ) cars [ i ]-> move (); массив указателей создание объектов
Слайд 25: Что в этом хорошего и плохого?
25 основная программа – простая и понятная классы могут разрабатывать разные программисты независимо друг от друга (+интерфейс!) повторное использование классов неэффективно для небольших задач ООП – это метод разработки больших программ!
Слайд 26: Объектно-ориентированное программирование. Языки C++ и C#
§ 49. Скрытие внутреннего устройства 26 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 27: Зачем скрывать внутреннее устройство?
27 Объектная модель задачи : ? ? интерфейсы защита внутренних данных проверка входных данных на корректность изменение устройства с сохранением интерфейса Инкапсуляция («помещение в капсулу») – скрытие внутреннего устройства объектов. Также объединение данных и методов в одном объекте! !
Слайд 28: Пример: класс «перо»
class TPen { private : string FColor; public : string getColor (); void setColor ( string newColor ); }; Пример: класс «перо» 28 class TPen { private : string FColor; // цвет, " FF 00 FF " }; R G B По умолчанию все члены класса закрытые – private ! ! Как к ним обращаться? ? F ield – поле string getColor (); void setColor ( string newColor ); методы доступа
Слайд 29: Пример: класс «перо»
29 Получить значение : string TPen::getColor () { return FColor; } Записать значение : void TPen::setColor ( string newColor ) { if ( newColor.length()!= 6 ) FColor = "000000" ; else FColor = newColor; } если ошибка, чёрный цвет Защита от неверных данных! !
Слайд 30: Пример: класс «перо»
30 Использование : TPen pen; pen.set Color ( " FFFF 00" ); cout << "цвет пера: " << pen. getColor (); установить цвет Не очень удобно! ! прочитать цвет pen. color = " FFFF 00" ; cout << pen. color ; нельзя в C++
Слайд 31: Изменение внутреннего устройства
31 class TPen { private : int FColor; public : string getColor(); void setColor( string newColor ); }; Удобнее хранить цвет в виде числа : string getColor(); void setColor( string newColor ); int Интерфейс не изменился! ! изменилось внутреннее устройство Найди отличие! ?
Слайд 32: Преобразования int hex
32 # include < sstream > Использование потока ( байтов ) : 255 " FF" записываем в поток число в шестнадцатеричной системе читаем строку подключить строковые потоки stringstream s ; s << hex << FColor; Что плохо? ? " 0000FF" правильно так! 16711935 " FF00FF"
Слайд 33: Преобразования hex ↔ int
string TPen :: getColor () { stringstream s; s << setfill( '0' ) << setw( 6 ) << hex << FColor; return s. str (); } Преобразования hex ↔ int 33 # include < sstream > # include < iomanip > 255 "0000 FF" подключить манипуляторы заполнять не пробелами, а нулями вывести 6 знаков прочитать строку string из потока
Слайд 34: Преобразования hex int
34 void TPen::setColor ( string newColor ) { stringstream s; if ( newColor.length()!= 6 ) FColor = 0 ; // чёрный цвет else { s << newColor; s >> hex >> FColor; } } Использование потока : 16711935 " FF00FF" записываем в поток строку читаем число в шестнадцатеричной системе записываем строку читаем число
Слайд 35: Свойства в C#
35 Свойство – это способ доступа к внутреннему состоянию объекта, имитирующий обращение к его внутренней переменной. Доступ с помощью методов : TPen pen; pen.set Color ( " FFFF 00" ); cout << "цвет пера: " << pen. getColor (); Доступ с помощью свойства color : TPen pen; pen. color = " FFFF 00" ; cout << "цвет пера: " << pen. color ; вызов pen.setColor вызов pen.getColor
Слайд 36: Свойства в C#
36 class TPen { private string FColor; public string color { get { return FColor; } set { FColor = value ; } } } метод чтения метод записи закрытое поле открытое свойство Использование : TPen pen; pen. color = " FFFF 00" ; string s = pen. color ;
Слайд 37: Свойства в C#
37 Защита от неверного ввода данных : public string color { get { return FColor; } set { if ( value.Length != 6 ) FColor = "000000" ; else FColor = value ; } } переданное значение
Слайд 38: Свойства в C#
38 Изменение внутреннего устройства : class TPen { private int FColor; public string color { get { return FColor.ToString ( "X6" ); } set { FColor = Convert.ToInt32( value, 16); } } } в строку шестнадцатеричныйформат, 6 знаков в целое из шестнадцатеричной записи переданное значение Данные – целое число, свойство – строка! !
Слайд 39: Свойство «только для чтения»
39 class TCar { private : double Fv; public : double getV() { return Fv; } }; нет метода записи Скорость машины можно только читать : class TCar { private double Fv; public double V { get { return Fv; } } }; Свойство на C# :
Слайд 40: Скрытие внутреннего устройства
40 свойства методы Инкапсуляция («помещение в капсулу») интерфейс ( public ) внутреннее устройство ( private )
Слайд 41: Объектно-ориентированное программирование. Языки C++ и C#
§ 50. Иерархия классов 41 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 42: Классификации
42 Классификация – разделение изучаемых объектов на группы (классы), объединенные общими признаками. Зачем это нужно? ? Яблоко Груша Банан Апельсин базовый класс Фрукт классы-наследники это фрукт, у которого… Что такое классификация? ?
Слайд 43: Что такое наследование?
43 класс Двудольные семейство Бобовые род Клевер горный клевер наследует свойства (имеет все свойства) Класс Б является наследником класса А, если можно сказать, что Б – это разновидность А. яблоко – это фрукт машина – двигатель яблоко – фрукт горный клевер – клевер горный клевер – это растение рода Клевер машина содержит двигатель (часть – целое)
Слайд 44: Иерархия логических элементов
44 Логический элемент с одним входом с двумя входами ИЛИ И НЕ Объектно-ориентированное программирование – это такой подход к программированию, при котором программа представляет собой множество взаимодействующих объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.
Слайд 45: Базовый класс
45 ЛогЭлемент In 1 (вход 1) In 2 (вход 2) Res (результат) calc class TLogElement { public : bool In1, In2, Res; void calc(); }; Зачем хранить результат? ? можно моделировать элементы с памятью (триггеры) вычислить выход Что плохо? ?
Слайд 46: Базовый класс
46 class TLogElement { private : bool FIn1, Fin2, FRes; void calc(); public : bool getIn1() { return FIn1; } void setIn1 ( bool newIn1 ); bool getIn2() { return Fin2; } void setIn2 ( bool newIn2 ); bool getRes() { return FRes; } }; Почему здесь? ? только для чтения
Слайд 47: Установка входа
47 void TLogElement ::setIn1( bool newIn1) { FIn 1 = newIn 1; calc (); } пересчёт при изменении входа Как написать процедуру calc ? ? void TLogElement :: calc () { } заглушка Проблема: наследники должны менять calc ! ! Что ещё? ?
Слайд 48: Что такое полиморфизм?
48 греч. : πολυ — много, μορφη — форма Полиморфизм – это возможность классов-наследников по-разному реализовать метод, описанный для класса-предка. Проблема: открыть данные и методы для наследников и закрыть для остальных! ! class TLogElement { ... protected : void calc(); }; защищённые элементы: доступны только наследникам
Слайд 49: Базовый класс
49 class TLogElement { private : bool FIn1, Fin2; protected : bool FRes ; virtual void calc ()= 0 ; bool getIn2() { return Fin2; } void setIn2 ( bool newIn2 ); public : bool getIn1() { return FIn1; } void setIn1 ( bool newIn1 ); bool getRes () { return FRes ; } }; наследники будут изменять поле virtual = 0 ;
Слайд 50: Базовый класс
50 class TLogElement { protected : bool FRes; virtual void calc()= 0 ; bool getIn2() { return Fin2; } void setIn2 ( bool newIn2 ); ... }; наследники будут изменять поле virtual = 0 ; для элементов с одним входом не нужно! virtual ( виртуальный ) – этот метод могут переопределять классы-наследники = 0 ( абстрактный метод) – этот метод базовый класс не будет реализовывать (оставляет наследникам)
Слайд 51: Абстрактный класс
51 Абстрактный метод – это метод класса, который объявляется, но не реализуется в классе. Абстрактный класс – это класс, содержащий хотя бы один абстрактный метод. все логические элементы должны иметь метод calc метод calc невозможно написать, пока неизвестен тип логического элемента нет логического элемента «вообще», как не «фрукта вообще», есть конкретные виды Нельзя создать объект абстрактного класса! ! TLogElement – абстрактный класс из-за метода calc
Слайд 52: Элемент «НЕ»
52 class TNot : public TLogElement { protected : void calc (); }; void TNot :: calc () { FRes =! getIn 1(); } Это уже не абстрактный класс! ! наследник от TLogElement переопределяет метод базового класса Почему не ! FIn1 ? ?
Слайд 53: Элемент «НЕ»
53 TNot n; n.setIn1 ( false ); cout << n. getRes (); Использование : создание объекта установка входа вывод результата
Слайд 54: Элементы с двумя входами
54 class TLog2In: public TLogElement { public : TLogElement ::setIn2; TLogElement ::getIn2; }; наследник от TLogElement повысить «видимость» ( protected public ) Можно ли создать объект этого класса? ? нельзя, он абстрактный сохранить права доступа
Слайд 55: Элементы с двумя входами
55 class TAnd : public TLog2In { protected : void calc (); }; class T Or : public TLog2In { protected : void calc (); }; элемент «И» элемент «ИЛИ»
Слайд 56: Элементы с двумя входами
56 void TAnd :: calc () { FRes = getIn1() && getIn2(); } void TOr :: calc () { FRes = getIn1() || getIn2(); } элемент «И» элемент «ИЛИ» доступ к защищённому полю ( protected ) Почему не обратиться к FIn1 и FIn2 ? ?
Слайд 57: Вызов виртуального метода
57 void TLogElement::setIn1( bool newIn1 ) { FIn1 = newIn1; calc(); } В базовом классе : Какой метод вызывается? ? class TLogElement { protected : virtual void calc()= 0 ; ... }; virtual
Слайд 58: Виртуальный метод
58 Виртуальный метод – это метод базового класса, который могут переопределить классы-наследники так, что конкретный адрес вызываемого метода определяется только при выполнении программы. Статическое связывание : транслятор записывает в код адрес процедуры Динамическое связывание : адрес процедуры определяется во время выполнения программы в зависимости от типа объекта
Слайд 59: Пример: элемент «И-НЕ»
59 main () { TNot elNot; TAnd elAnd; int A, B; cout << " A B !(A&B)" << endl; cout << "-------------" << endl; for ( A = 0; A <= 1; A++ ) { elAnd.setIn1 ( A ); for ( B = 0; B <= 1; B++ ) { elAnd.setIn2 ( B ); elNot.setIn1 ( elAnd.getRes() ); cout << " " << A << " " << B << " " << elNot.getRes() << endl; } } } &
Слайд 60: Модульность
60 class TLogElement { … } class TLog2In: public TLogElement { … } class TNot : public TLogElement { … } class TAnd : public TLog 2 In { … } class TOr : public TLog 2 In { … } Идея : выделить классы в отдельный модуль. Интерфейс ( log_elem.h ) :
Слайд 61: Модульность
61 void TLogElement::setIn1 ( bool newIn1 ) {... } void TLogElement::setIn2 ( bool newIn1 ) {... } void TNot::calc() {... } void TAnd::calc() {... } void TOr::calc() {... } #include < log_elem.h > Модуль ( log_elem.cpp ) : реализация методов классов Чего не хватает? ? В основную программу : #include < log_elem.h >
Слайд 62: Сообщения между объектами
62 Задача – автоматическая передача сигналов по цепочке! ! class TLogElement { private : TLogElement *FNextEl; int FNextIn; ... public : void Link ( TLogElement *nextElement, int nextIn = 1 ); }; адрес следующего элемента в цепочке номер входа следующего элемента
Слайд 63: Сообщения между объектами
63 void TLogElement::Link( TLogElement *nextElement, int nextIn ) { FNextEl = nextElement; FNextIn = nextIn; } Установка связи :
Слайд 64: Сообщения между объектами
64 void TLogElement::setIn1 ( bool newIn1 ) { FIn1 = newIn1; calc(); if ( FNextEl ) switch ( FNextIn ) { case 1 : FNextEl->setIn1 ( getRes() ); case 2 : FNextEl->setIn2 ( getRes() ); } } После изменения выхода «дергаем» следующий элемент : если следующий элемент установлен… передать результат на нужный вход
Слайд 65: Сообщения между объектами
65 TLogElement::TLogElement() { FNextEl = NULL ; } Как сделать, чтобы сначала FNextEl = NULL ? ? Новый конструктор :
Слайд 66: Сообщения между объектами
66 TNot elNot; TAnd elAnd; elAnd.Link ( &elNot ); ... for ( A = 0; A <= 1; A ++ ) { elAnd.setIn1 ( A ); for ( B = 0 ; B <= 1 ; B++ ) { elAnd.setIn2( B ); elNot.setIn1(elAnd.getRes()); ... } } Изменения в основной программе : elAnd. Link ( & elNot ); установить связь это уже не нужно!
Слайд 67: Объектно-ориентированное программирование. Языки C++ и C#
§ 51. Программы с графическим интерфейсом 67 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 68: Интерфейс: объекты и сообщения
68 поле ввода кнопка флажок переключатель Все элементы окон – объекты, которые обмениваются данными, посылая друг другу сообщения. Сообщение – это блок данных определённой структуры, который используется для обмена информацией между объектами. адресат (кому) или широковещательное числовой код (тип) сообщения параметры (дополнительные данные)
Слайд 69: Классические программы
69 процедуры и функции Порядок выполнения команд определяется программистом, пользователь не может вмешаться! ! ввод данных обработка данных вывод результатов конец начало основная программа
Слайд 70: Программы, управляемые событиями
70 Событие – это переход какого-либо объекта из одного состояния в другое. нажатие на клавишу щелчок мышью перемещение окна поступление данных из сети запрос к веб-серверу завершение вычислений … Программа начинает работать при наступлении событий! !
Слайд 71: Программы, управляемые событиями
программа обработчики сообщений операционная система системная очередь сообщений клавиатура, мышь, … Программы, управляемые событиями 71 основная программа очередь программы конец ожидание сообщения обработка сообщения начало стоп? Программа управляется событиями! !
Слайд 72: Что такое RAD- среда?
72 RAD = Rapid Application Development — быстрая разработка приложений создание формы минимальный код добавляется автоматически расстановка элементов интерфейса с помощью мыши и настройка их свойств создание обработчиков событий написание алгоритмов обработки данных Этапы разработки: Форма – это шаблон, по которому строится окно программы или диалога выполняются при возникновении событий
Слайд 73: RAD- среды : Delphi
73 Язык: Object Pascal, позднее Delphi : 1995: Borland, сейчас: Embarcadero Technologies
Слайд 74: RAD- среды : MS Visual Studio
74 Языки: Visual Basic, Visual C++, Visual C#, Visual F# c 1995 по н.в. : Microsoft
Слайд 75: RAD- среды : Lazarus
75 Языки: FreePascal, Delphi свободное ПО: lazarus.freepascal.org
Слайд 76: Объектно-ориентированное программирование. Языки C++ и C#
§ 52. Программирование в RAD- средах 76 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 77: Visual Studio Express ( C# )
77 http://www.visualstudio.com/ru-ru/products/visual-studio-express-vs.aspx
Слайд 78: Язык C#
78 С С++ C# Паскаль Smalltalk Java C# F# VB.NET язык CIL (байт-код) Common Intermediate Language виртуальная машина CLR Common Language Runtime объединение программ на разных языках полностью ООП – для больших программ большая библиотека функций и компонентов требовательна к ресурсам надёжно – только под Windows Linux – проект Mono
Слайд 79: Проекты и решения
Form 1. resx 79 Проект – это набор файлов, из которых компилятор строит исполняемый файл программы. проект (. csproj, CSharp Project ) – описание ( XML ) модули, из которых состоит программа ( *.с s ); ресурсы ( *. resx ) – строки (перевод сообщений). Проекты и решения Program.cs Form 1. Designer. cs Form1. cs my.exe основная программа обработчики событий ресурсы описание формы Решение = один или несколько проектов.
Слайд 80: Простейший проект
80 Файл – Создать проект – Приложение Windows Forms Свойства Панель элементов Редактор кода Конструктор формы F5 – запуск! ! Структура проекта
Слайд 81: Модуль формы
81 F 7 – перейти из конструктора к коду формы using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Project1 { public partial class Form1 : Form { public Form1(){ InitializeComponent(); } } } библиотеки пространство имён конструктор
Слайд 82: Модуль формы
82 public partial class Form1 : Form { public Form1() { InitializeComponent(); } } открытый класс частичное описание наследник класса Form начальные установки Код этого метода – в Form1.Designer.cs ! !
Слайд 83: Основная программа
83 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace Project1 { static class Program { static void Main() { ... Application.Run ( new Form1() ); } } } библиотеки статический класс создание формы запуск цикла обработки сообщений Статический класс – набор методов! !
Слайд 84: Свойства формы
84 Name – имя формы Size.Width – ширина Size.Height – высота Text – текст в заголовке окна Back Color – цвет фона Font – шрифт надписей MainForm
Слайд 85: Обработчик событий
85 2 ЛКМ: создать обработчик FormClosing : форма закрывается События
Слайд 86: Обработчик события
86 private void MainForm_FormClosing ( object sender, FormClosingEventArgs e ) { } закрытый метод класса MainForm название обработчика общий предок всех объектов кто послал сообщение дополнительные данные о событии Автоматически добавлен в Form1.Designer.cs ! !
Слайд 87: Диалог с вопросом
private void MainForm_FormClosing ( object sender, FormClosingEventArgs e) { DialogResult res; res = MessageBox.Show ( "Вы действительно хотите выйти из программы?", "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question ); if ( res == DialogResult.No ) e. Cancel = true ; } тип: результат диалога Диалог с вопросом 87 Метод MessageBox.Show : нажали « Нет », отменить закрытие
Слайд 88: Параметры MessageBox.Show
88 сообщение пользователю заголовок окна тип запроса MessageBoxIcon Error ошибка Warning предупреждение Information информация Question вопрос набор (множество) кнопок MessageBoxButtons : YesNo «Да», «Нет» YesNoCancel «Да», «Нет», «Отмена» OK « OK » OKCancel «ОК», «Отмена»
Слайд 89: Объектно-ориентированное программирование. Языки C++ и C#
§ 53. Использование компонентов 89 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 91: Просмотр рисунков
91 панель Panel выключатель CheckBox рисунок PictureBox кнопка Button
Слайд 92: Настройка формы
92 Файл – Создать проект – Приложение Windows Forms Name MainForm Text Просмотр рисунков
Слайд 94: Кнопка и выключатель
94 кнопка Button выключатель CheckBox Name = OpenBtn Text = Открыть файл Name = SizeCB Text = По размерам окна
Слайд 95: Компонент PictureBox
95 рисунок PictureBox Name = Image Dock = Fill 1) Загрузка файла? 2) Масштабирование? ?
Слайд 97: Выбор файла
97 if ( OpenDlg.ShowDialog() == DialogResult.OK ) Img.Image = new Bitmap (OpenDlg.FileName); если файл выбран имя файла 2 ЛКМ
Слайд 98: Масштабирование
98 2 ЛКМ if ( SizeCB.Checked ) Img.SizeMode = PictureBoxSizeMode.Zoom; else Img.SizeMode = PictureBoxSizeMode.Normal;
Слайд 99: Ввод и вывод данных
99 для веб-страниц метка rgbLabel Label панель rgbPanel Panel поле ввода rEdit TextBox поле ввода bEdit TextBox поле ввода gEdit TextBox метки Label
Слайд 101: Обновление компонентов вывода
101 private void rEdit_TextChanged ( object sender, EventArgs e ) { int r, g, b; r = Int32.Parse ( rEdit.Text ); g = Int32.Parse ( gEdit.Text ); b = Int32.Parse ( bEdit.Text ); rgbPanel.BackColor = Color.FromArgb ( r, g, b ); rgbLabel.Text = "#" + r.ToString( "X2" ) + g.ToString( "X2" ) + b.ToString( "X2" ); } из строки в число построить цвет в шестнадцатеричную систему, 2 знака
Слайд 102: Вызов при запуске
102 private void MainForm_Load ( object sender, EventArgs e ) { rEdit_TextChanged ( rEdit, e ); } private void MainForm_Load ( object sender, EventArgs e ) { rEdit_TextChanged ( null, null ); } пустой объект вызывающий объект – rEdit ( здесь – всё равно! )
Слайд 103: Обработка ошибок
103 Если вместо числа ввести букву? ? Программа не должна «вылетать»! !
Слайд 104: Обработка ошибок
104 try { // «опасные» команды } catch { // обработка ошибки } попытаться выполнить если исключение (аварийная ситуация) Какие у нас опасные операции? ?
Слайд 105: Обработка ошибок
105 try { r = Int32.Parse ( rEdit.Text ); g = Int32.Parse ( gEdit.Text ); b = Int32.Parse ( bEdit.Text ); rgbPanel.BackColor = Color.FromArgb ( r, g, b ); rgbLabel.Text = "#" + r.ToString( "X2" ) + g.ToString( "X2" ) + b.ToString( "X2" ); } catch { rgbLabel. Text = "?" ; } rgbLabel. Text = "?" ; если ошибка, записать "?" Что делать, если ошибка? ?
Слайд 106: Блокирование неверных символов
106 private void rEdit_KeyPress ( object sender, KeyPressEventArgs e ) { if ( ! ( Char.IsDigit(e.KeyChar) || e.KeyChar == ( char ) 8) ) e.Handled = true ; } Backspace выделить все три (+ Shift ) обработка завершена это цифра
Слайд 107: Объектно-ориентированное программирование. Языки C++ и C#
§ 54. Совершенствование компонентов 107 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 108: Новый класс (модуль)
108 Задача : построить поле для ввода целых чисел, в котором есть защита от ввода неверных символов есть методы для чтения / записи целого числа На основе класса TextBox ! ! class IntTextBox : TextBox { } Проект – Добавить класс using System.Windows.Forms ; там объявлен TextBox F5 – запуск! И компонент в палитре! !
Слайд 109: Обработчик KeyPress
109 class IntTextBox : TextBox { protected override void OnKeyPress ( KeyPressEventArgs e ) { if ( !( Char.IsDigit(e.KeyChar) || e.KeyChar == ( char ) 8 ) ) e.Handled = true ; base.OnKeyPress(e); } } только для наследников перекрыть метод базового класса base.OnKeyPress(e); вызвать метод базового класса
Слайд 110: Свойство Value
110 class IntTextBox : TextBox { ... public int Value { set { Text = value.ToString(); } get { try { return Int32.Parse(Text); } catch { return 0 ; } } } } общедоступное свойство число в строку из строки в число
Слайд 111: Поле для ввода целых чисел
111 private void decEdit_TextChanged ( object sender, EventArgs e ) { hexLabel.Text = decEdit.Value.ToString ( "X" ); } Использование : метка hexLabel Label поле ввода decEdit IntTextBox свойство в шестнадцатеричную
Слайд 112: Объектно-ориентированное программирование. Языки C++ и C#
§ 55. Модель и представление 112 Объектно-ориентированное программирование. Языки C++ и C#
Слайд 113: Еще одна декомпозиция
решение Еще одна декомпозиция 113 Задача : повторное использование написанного ранее готового кода. модель (данные и методы их обработки) представление (интерфейс с пользователем) решение представление (интерфейс с пользователем)
Слайд 114: Модель и представление
модель представление представление решение Модель и представление 114 Задача : хранить и использовать данные об изменении курса доллара. модель (массив, поиск минимума и максимума, прогнозирование) представление (формулы, диаграммы, графики, таблицы) x y z 1 1 4 2 2 5 3 3 6
Слайд 115: Модель и представление
115 Задача : вычисление арифметического выражения: целые числа знаки арифметических действий + - * / Модель : символьная строка алгоритм вычисления: k = номер последней операции n1 = значение левой части n2 = значение правой части результат = операция (n1, n2) 22 + 13 – 3 * 8 n1 n2 k функция LastOp ( глава 6 ) Рекурсия! ! Чего не хватает? ?
Слайд 116: Модель
116 k = номер последней операции if ( k < 0 ) результат := строка в число else { n1 = значение левой части n2 = значение правой части результат = операция (n1, n2) } Псевдокод :
Слайд 117: Статический класс – набор функций
117 static class Calculator { static int Priority ( char op ) { ... } static int LastOp ( string s ) { ... } public static int Calc ( string s ) { ... } } Проект – Добавить класс приоритет операции последняя операция вычислить Calc – открытый метод! !
Слайд 118: Модель: приоритет операций
118 int Priority ( char op ) { switch ( op ) { case '+' : case '-' : return 1 ; case '*' : case '/' : return 2 ; } return 100 ; }
Слайд 119: Модель: номер последней операции
119 int LastOp ( string s ) { int i, minPrt, res; minPrt = 50 ; // любое между 2 и 100 res = -1 ; for ( i = 0 ; i < s. Length ; i ++ ) if ( Priority(s[ i ]) <= minPrt ) { minPrt = Priority(s[ i ]); res = i ; } return res; } <= Почему <= ? ? вернёт номер символа
Слайд 120: Модель: вычисления
120 public static int Calc( string s) { int k, n1, n2, res = 0 ; k = LastOp ( s ); if ( k < 0 ) return Int32.Parse(s); n1 = Calc( s.Substring( 0, k) ); // левая n2 = Calc( s.Substring(k+1) ); // правая switch ( s[k] ) { case '+' : res = n1 + n2; break ; case '-' : res = n1 - n2; break ; case '*' : res = n1 * n2; break ; case '/' : res = n1 / n2; break ; } return res; }
Слайд 121: Представление
121 многострочное поле TextBox выпадающий список ComboBox Name = Answers Dock = Fill ReadOnly = True Multiline = True Name = Input Dock = Top if ( нажата клавиша Enter ) { x = значение выражения добавить результат в конец поля вывода if ( выражения нет в списке ) добавить его в список }
Слайд 122: Перехват нажатия на клавишу Enter
122 private void Input_KeyPress ( object sender, KeyPressEventArgs e ) { if ( e.KeyChar == ( char ) 13 ) { ... } } KeyPress для элемента Input : if ( e.KeyChar == ( char ) 13 ) { ... } код клавиши Enter
Слайд 123: Обработка и вывод данных
123 int x; x = Calculator.Calc( Input.Text); Вычисления (обращение к модели) : Answers.Text += Input.Text + "=" + x.ToString() + "\r\n" ; Добавление строки в TextBox : добавить строку число в строку новая строка
Слайд 124: Обработка и вывод данных
124 int i = Input.FindString(Input.Text); if ( i < 0 ) Input.Items.Insert ( 0, Input.Text ); Добавление строки в ComboBox : Input.Items вставить строку найти индекс строки массив строк в ComboBox позиция списка что вставлять
Слайд 125: Перехват нажатия на клавишу Enter
125 private void Input_KeyPress ( object sender, KeyPressEventArgs e ) { if ( e.KeyChar == ( char ) 13 ) { int x = Calculator.Calc ( Input.Text ); Answers.Text += Input.Text + "=" + x.ToString() + "\r\n" ; int i = Input.FindString(Input.Text); if ( i < 0 ) Input.Items.Insert( 0, Input.Text); } } KeyPress для элемента Input :
Слайд 127: Конец фильма
127 Конец фильма ПОЛЯКОВ Константин Юрьевич д.т.н., учитель информатики ГБОУ СОШ № 163, г. Санкт-Петербург kpolyakov@mail.ru ЕРЕМИН Евгений Александрович к.ф.-м.н., доцент кафедры мультимедийной дидактики и ИТО ПГГПУ, г. Пермь eremin@pspu.ac.ru