420 likes | 685 Views
Высокоуровневые методы информатики и программирования Лекция 1 1 - 12 Наследование классов. План лекции. Связи между классами Агрегация классов Наследование классов Скрытие методов Переопределение методов. Связи между классами. Связь классов программы.
E N D
Высокоуровневые методы информатики и программированияЛекция 11-12Наследование классов
План лекции • Связи между классами • Агрегация классов • Наследование классов • Скрытие методов • Переопределение методов
Связь классов программы • Часто классы программы связаны между собой • Два типа связи • агрегирование (ассоциация, has-a) - класс содержит объекты другого класса; • наследование (is-a) - один класс может быть производным от другого класса – наследовать его поля, свойство, методы • Множество классов описывающих решаемую задачу называются - модель предметной области
Взаимозависимости классов в UML Типы взаимозависимостей (relationship) • зависимость (dependency) – один класс временно использует (или знает) о другом классе, самая слабая, временная связь; • ассоциация (association) – один класс использует объекты другого класса (has a) • агрегирование (aggregation) – более сильная ассоциация между классами (owns a) • композиция (composition) – очень сильная взаимосвязь между классами, отношение «часть-целое» (part-of) • обобщение (generalization)отношение наследования (“являться”, “is a”)
UML обозначения • зависимость (dependency) • ассоциация (association) • агрегирование (aggregation) • композиция (composition) • наследование, обобщение (generalization)
Наследование • Один класс может быть производным от другого класса (базового). • Класс может быть наследником только одного базового класса • Производный класс может использовать поля, свойства и методы базового класса (и классов для которых он является производным). • Все классы наследуются от базового класса System.Object, которыйсодержит • конструктор по умолчанию new() • ToString(); • GetType(); • GetHashCode(); • Equals().
Universal Modeling Language диаграмма • Universal Modeling Language (UML)язык для моделирования программ (программных систем). • UML включает набор диаграмм для описания проектируемых программ. • В UML есть диаграмма классов. Базовый класс (Родительский класс) Производный класс (дочерний класс)
Human Manager "IS A" Human Programmer "IS A" Human Manager Programmer SeniorManager ManagerTrainee Наследование
Наследование типов в CLR Object String Array ValueType Exception Delegate Class1 Встроенные типы Enum Structure1 Multicast Delegate Class2 Boolean Char Byte Single Enum1 Class3 Int16 Double Int32 Decimal - Типы, описанные в системе DateTime Int64 - Типы, описанные разработчиками
Иерархия классовэлементов управления Control ButtonBase Label TreeView Button CheckBox RadioButton LinkLabel
Происхождение класса форм Form Object . . . Control ScrollableControl ContainerControl Form
Правило наследования Два класса, которые могут быть связаны с помощью отношения наследования должны пройти тест “является видом …” ("is a" test.) Например: • Треугольник является видом фигуры • Руководитель является видом служащего • Легковой автомобиль является видом транспортного средства Например нельзя наследовать: велосипед не является видом колеса
Методы класса System.Object • Equals() - виртуальный метод, возвращающий true если значения объектов совпадают (по умолчанию,если два объекта расположены в одном месте памяти). • GetHashCode() - виртуальный метод, возвращает некоторое целое число (хэш-код), однозначно идентифицирующее экземпляр класса. • GetType() - возвращает объект типа Type, описывающий соответствующий тип. • ToString() - виртуальный метод, возвращающий символьное представление значения переменной (по умолчанию возвращает строку, представляющую полное имя типа объекта).
Equals() – по умолчанию этот метод возвращает true только в том случае, если сравниваемые элементы ссылаются на один и тот же объект в оперативной памяти. Таким образом,Equals() используется для сравнения ссылок на объект, а не состояния объекта. Обычно этот метод переопределяется (overridden) для возврата true в том случае, если сравниваемые объекты имеют одинаковые значения полей (internal statevalues). При переопределении Equals() также нужно переопределить методGetHashCode(), так как он используется типом Hashtableдля поиска объектов в коллекциях. • GetHashCode() – этот метод возвращает целое число, которое идентифицирует конкретный экземпляр объекта класса. • GetType() – этот метод возвращает объект типа Type, который полностью описывает объект, на который выполняется ссылка. Это метод динамической идентификации типа объекта (Runtime TypeIdentification, RTTI), который доступен для всех объектов. • ToString() – этот метод возвращает текстовое описание объекта, используя формат <namespace>.<type name> (называемоеfully qualifiedname). Данный метод может быть переопределен в производном классе для возвращения строки с парами им/значения для описания внутреннего состояния объекта.
Хэш-код • Хэш-функция (функция свёртки) ― это функция, отображающая аргумент произвольной конечной длины в образ фиксированной длины. • Результат работы данной функции называют хэш-кодом, хэшемили дайджестом сообщения (англ. messagedigest). • Если хэш-функция зависит от секретного ключа, то она называется ключевой, в противном случае бесключевой. • Простым примером хеширования может служить нахождение контрольной суммы сообщения: сумма кодов всех входящих в него символов, от которой берётся несколько последних цифр. Полученное число является примером хэш-кода исходного сообщения.
Описание производного класса public class <new class> : <base class> { … } • Наследование может быть только от одного класса • Пример public class ColorPoint : Point { … }
Объект производного класса имеет доступ ко всем • Открытым (public) свойствам и методам базового класса • Защищенным (protected) свойствам и методам базового класса • Методам переопределенным (override) в производном классе • Свойствам и методам скрытым (new) в производном классе • Любым свойствам и методам производного класса
Изолированные классы • Можно создать класс, у которого не должны быть производные классы. • Для этого используется ключевое слово sealed, которое сообщает компилятору, что для описываемого класса нельзя создавать наследников. • Например, вы решили, что нет смысла делать наследников от класса MiniVan: // Данный класс нельзя наследовать! sealed class MiniVan : Car { } • Если вы попытаетесь сделать класс производный от MiniVan то получите сообщение об ошибке: // Error! Cannot extenda class marked with the sealed keyword! class DeluxeMiniVan : MiniVan { … }
В библиотеке FCL описано большое количество закрытых классов:
Диаграммы классов • Добавление диаграммы классов к проекту:
Наследование public Manager(string fullName, int age, int empID, float currPay, string ssn, int numbOfOpts) : base(fullName, age, empID, currPay, ssn) { // This field is defined by the Manager class. numberOfOptions = numbOfOpts; }
Сохранение семейных секретов:режим доступа protected • Режим доступа:protected • К элементам класса с режимом доступа protectedимеется доступ в методах самого класса и методах производных классов.
Диаграмма наследования class ClassA class ClassB : ClassA class ClassC : ClassB ClassA Методы Свойства Поля Все методы, свойства и поля - public и protected ClassB Новые Наследуемые от А Методы Свойства Поля Методы Свойства Поля ClassC Новые Наследуемыеот B Наследуемыеот А Методы Свойства Поля Методы Свойства Поля Методы Свойства Поля Элементы класса С
Конструктор производного класса • Конструктор производного класса может вызывать на выполнение требуемый конструктор базового класса. рublic Circle (int a, int b, int r) : base(a, b) { base._x = 0; // обращение в переменной // базового класса }
Операция присвоения T1 e = new T1();T2 x; x = e • Присваивание допустимо, если и только если имеет место согласование типов. • Определение: тип T1(для e) согласован по присваиванию с базовым типом T (для x), если они совпадают или если класс T1 является потомкомкласса T.
Правило присвоения ссылочных переменных • Нельзя присвоить переменную одного класса переменной другого класса Car a = new Car; Book b = new Book; a = b; //Value of type ‘Book' cannot be converted to ‘Car' • Можно присвоить переменной базового класса значение переменной производного класса MyBaseClass a = new MyBaseClass; MyNewClass b = new MyNewClass; // производный от MyBaseClass a = b; //Value of type ' MyNewClass' can be converted to ' MyBaseClass‘ b = a; //Value of type ' MyBaseClass ' cannot be converted to ' MyNewClass‘ Debug сообщения: • An unhandled exception of type 'System.InvalidCastException' occurred in Xxxxx.exe • Additional information: Specified cast is not valid.
Тип объекта и тип ссылки • Следует всегда различать • тип объекта (type of object)который используется • тип ссылки (type of reference)с помощью которой взаимодействуют с объектом. ClassA a; // тип ссылки ClassA(базовый) a = new ClassB;// тип объекта ClassB (производный) • Статическое и динамическое связывание ссылочная переменная Объект
Изменение методов в производном классе Если в производном классе есть метод с именем и сигнатурой идентичной методу базового класса, то он может: • скрывать (shadowing) метод базового класса, т.е. работать только с использованием ссылки производного типа • заменять (переопределять, overriding) метод базового класса, т.е. работать с ссылками и производного и базового типа
Скрытие метода базового класса public class A { public void Print ( ) // может быть и virtual { Console.WriteLine("Class A"); } } public class B : A { public new void Print ( ) { Console.WriteLine("Class B"); } } …. Aa; Bb = new B( ); b.Print( ); // "Class B" a = b; a. Print( ); // "Class A" ….
Замена метода базового класса public class A { public virtual void Print ( ) { Console.WriteLine("Class A"); } } public class B : A { public override void Print ( ) { Console.WriteLine("Class B"); } } …. Aa; Bb = newB( ); b.Print( ); // "Class B" a = b; a.Print( ); // "Class B" …
Изолированные методы public override sealed void TraceSelf( ) { ... }
Пример • Figure • Rectangle • Triangle • Point
24386 Базовый класс MyClass class MyBaseClass { private int v; public int Val {…} . . . public int fn(…) {…} . . . } . . . MyBaseClass a = new MyBaseClass; n = a.fn(); MyBaseClass b; b = a Val fn 24386 v 24386 Nothing
Производный класс – скрытие функции MyNewClass MyBaseClass class MyNewClass : MyBaseClass { private int v1; рublic int Val1 {…} . . . public new int fn(…) { … } . . . } . . . MyNewClass a = new MyNewClass; n = a.fn(); // функция нового класса . . . MyBaseClass b; b = a; n = b.fn(); // функция базового класса Val1 Val fn fn 24386 v v v1 24386 Ссылка на производный класс Ссылка на базовый класс Вызываемая функция определяется типом ссылки
Производный класс – переопределение функции MyNewClass MyBaseClass class MyBaseClass { . . . public virtual int fn(…) {…} . . . } class MyNewClass : MyBaseClass { . . . public override int fn(…){ … } . . . } MyNewClass a = new MyNewClass; n = a.fn(); // функция нового класса MyBaseClass b; b = a; n = b.fn(); // функция базового класса Val1 Val fn fn vtb vtb 24386 v v v1 24386 Ссылка на производный класс Ссылка на базовый класс Вызываемая функция определяется типом объекта
Полиморфизм (Polymorphism) • Множество объектов может внешне выглядеть одинаково, но выполнять методы они могут по разному • С объектами производных классов можно работать, как с объектами базового класса • Используя полиморфизм можно создавать общие алгоритмы для любых объектов производных от базового класса
Person -Name -Address -Phone Salary() Seller Salary() Engineer Salary() Worker Salary() Наследование • Базовый класс (Base Class) • Person • Производные классы (Subclasses) • Employee • Customer • Student
Полиморфизм • Массив Persons Person[] Company = new Person[200]; Seller Ivan = new Seller(); Engineer Petr = new Engineer(); Company[0] = Ivan; Company[1] = Petr; decimal s = 0; foreach (Person p in Company) s += p.Salary();