Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float.

Презентация:



Advertisements
Похожие презентации
НГТУ, каф. ВТ Наследование в С++ Макаревич Л. Г.НГТУ, каф. ВТ Наследование в С++ Макаревич Л. Г.
Advertisements

Высокоуровневые методы информатики и программирования Лекция 14 Интерфейсы.
1 ©Павловская Т.А. (СПбГУ ИТМО) Курс «С#. Программирование на языке высокого уровня» Павловская Т.А.
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
Учебный курс Объектно-ориентированный анализ и программирование Лекция 7 Методы как средство реализации операций Лекции читает кандидат технических наук.
Полиморфизм. Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Наследование и полиморфизм. «Быть» или «Иметь» а так же «Точно» или «Как получится»
Наследование Полиморфизм ВЫЗОВ КОНСТРУКТОРОВ И ДЕСТРУКТОРОВ ПРИ НАСЛЕДОВАНИИ.
Классы в С#. Перечисления С# Перечисление задает конечное множество возможных значений, которые могут получать объекты класса перечисление. [атрибуты][модификаторы]
НаследованиеНаследование2 class Point { double x; double y; Color color; }; class Radius { Point center; double radius; };
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
Обобщения ( generics) Обобщения – это классы, структуры, интерфейсы и методы, в которых некоторые типы сами являются параметрами. Эти типы перечисляются.
Кафедра ОСУ, Java 2004 Слайд 1 Наследование Наследование позволяет использовать существующий класс для определения новых классов, т.е. способствует.
Интерфейсы Интерфейсом называется семейство методов и свойств, которые сгруппированы в единое целое и инкапсулируют какую-либо определенную функциональную.
Наследование Лекция 7. Основы наследования. Создание производных классов. Наследование является одной из основных особенностей объектно-ориентированного.
С# и ООП Формальное определение класса с C# Класс в C# - это пользовательский тип данных (user defined type), который состоит из данных (часто называемых.
1 Java 6. ИНТЕРФЕЙСЫ И ВНУТРЕННИЕ КЛАССЫ. 2 Интерфейсы Не являются классами Ни один из объявленных методов не может быть реализован внутри интерфейса.
Лекция 2 Наследование Наследование в Java имеет тот же смысл, что и в С++. Однако наследование в Java осуществляется при помощи ключевого слова extends.
Наследование. Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся.
Гайдар Магдануров Microsoft.
Транксрипт:

Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float average_ball;... } Базовый класс Производный класс Обобщение Конкретизация Производный класс наследует все поля и методы базового класса. C# не поддерживает множественное наследование. Класс может иметь только один непосредственный базовый класс. Наследование применимо только к классам. Структура не может быть ни базовым классом, ни производным.

Отношение агрегации и отношение наследования Наследование Отношение между классами Сильная зависимость между производным и базовым классом Отношение задается на этапе компиляциии и не может быть изменено в процессе выполнения программы Агрегация (класс содержит ссылки на объекты других классов) Отношение между объектами Слабая зависимость между агрегирующим и агрегируемым классами Это отношение может изменяться в процессе выполнения программы

Наследование и конструкторы class Person { public Person(string[] name) {... } } class Student : Person { public Student(string[] name, int course) : base(name) {... } } Вызов конструктора базового класса Конструктор базового класса вызывается при помощи ключевого слова base. Если в базовом классе нет конструктора по умолчанию, то конструктор производного класса должен содержать явный вызов конструктора базового класса. Если в базовом классе есть конструктор по умолчанию, то его явный вызов в производном классе не обязателен.

Полиморфизм Полиморфизм дословно означает множественность форм или видов. Метод, определенный в базовом классе, может быть реализован в любом из производных классов Class Person { public virtual void PrintData() {...} } class Student : Person { public override void PrintData() {... }... } class Teacher : Person { public override void PrintData() {... }... } void SomeMethod(Person s) { s.PrintData();... } Student std = new Student(); SomeMethod(std); Teacher tch = new Teacher(); SomeMethod(tch); За одним именем могут скрываться разные реализации. обозначение полиморфного метода

Ранее и позднее связывание class Person { public virtual void PrintData() {... } } class Student : Person { public override PrintData() {... }... } class Teacher : Person { public override void PrintData() {... }... }... void SomeMethod(Person ps) { ps.PrintData();... }... Student std = new Student(); SomeMethod(std); Teacher tch = new Teacher(); SomeMethod(tch) динамический тип ps не известен в момент компиляции Статический тип – тип переменной (выражения), которая используется для доступа к объекту. Всегда известен во время компиляции. Раннее связывание – вызов метода на основе статического типа. Объект производного класса всегда может быть неявно преобразован к базовому классу. Динамический тип – тип объекта, на который ссылается переменная или выражение. Может быть не известен на этапе компиляции. Позднее связывание – вызов метода на основе динамического типа.

Виртуальные методы Для определения полиморфного (виртуального) метода применяется ключевое слово virtual. Для переопределения виртуального метода используется ключевое слово override. Виртуальный метод не может быть статическим. class Person { public virtual void PrintData() {...} } class Student : Person { public override void PrintData() {... }... } class Teacher : Person { public override void PrintData() {... }... } void SomeMethod(Person ps) { ps.PrintData();... } Метод PrintData будет вызван в соответствии с динамическим типом ps Определение виртуального метода Переопределение виртуального метода. Переопределенный метод также является виртуальным и может быть переопределен.

Виртуальный метод ToString() Метод ToString() определен в классе System.Object как виртуальный: public class Object { public virtual string ToString(); … } public class Console { public static void WriteLine( object value ); … } В классе System.Console один из перегруженных методов WriteLine принимает параметр типа object: Метод Console.WriteLine ( object value ); выводит пустую строку, если value == null; выводит строку value.ToString(), если value != null.

Виртуальный метод ToString() -2 class Bs { protected string bs_name; public Bs (string bs_name) { this.bs_name = bs_name;} public override string ToString() { return "Bs: " + bs_name;} } class Dr : Bs{ protected int dr_value; public Dr (int dr_value, string bs) : base (bs) { this.dr_value = dr_value;} public override string ToString() { return "Dr: " + bs_name + "\t" + dr_value;} } //.. output Bs: white DR: green 123 Bs: red static void Main(string[] args) {Bs[] list = new Bs[4]; list[0] = new Bs ("white"); list[2] = new Dr ( 123, "green"); list[3] = new Bs ("red"); for (int j=0; j

Переопределение невиртуальных методов Для переопределения невиртуального метода используется ключевое слово new. class Person { public void Output() {...} } class Student : Person { public new void Output() {... }... } Определение невиртуального метода Переопределение (сокрытие) невиртуального метода Person ps = new Person(); ps.Output(); Student st = new Student(); st.Output(); // Будет вызван метод Output из класса Student Person ps1 = new Student(); ps1.Output(); // Будет вызван метод Output из класса Person При вызове неполиморфного метода используется статический тип.

Виртуальные методы и new class A { public virtual void f() { Console.WriteLine(A.f); } } class B : A { public override void f() { Console.WriteLine(B.f); } } class C : B { public new virtual void f() { Console.WriteLine(C.f); } } class D : C { public override void f() { Console.WriteLine(D.f); } } Метод C.f не переопределяет, а скрывает B.f public static void Main (string[] args) { D d = new D(); A a = d; B b = d; C c = d; a.f(); // B b.f(); // B c.f(); // D d.f(); // D }

Виртуальные методы и переопределение ABDa.fxx()b.fxx() f0() из Aиз B virtual f1() из Aиз B virtual f2()override f2() из D virtual f3()override f3()f3()из B virtual f4()override f4()virtual f4()из B virtual f5() override f5()из Aиз D f6()virtual f6()override f6()из Aиз D class B : A {…} class D : B {…} D d = new D(); A a = d; B b = d;

Виртуальные свойства Свойство определяется парой методов. Поэтому свойства могут быть виртуальными, абстрактными или статическими. Свойства могут быть переопределены или скрыты. Тип виртуального свойства (только для чтения, только для записи, для чтения и для записи) переопределить нельзя. Индексатор может быть виртуальным.

Сокрытие полей данных В производном классе можно определить поле данных с тем же именем, что и в базовом классе. class A { protected int a; public void f() { a = 10; // Присваивание полю данных класса A } class B : A { public new int a; // Поле a класса B скрывает public void g() { // поле a класса A a = 20; // Присваивание полю данных класса B }

Явное обращение к полям и методам базового класса Для явного доступа к полям и методам базового класса в методах производного класса применяется ключевое слово base. public class A { public string str; public void f() {... } public virtual void g() {... } } public class B : A { public new string str; public new void f() {... } public override void g() {... } public void h() { base.str = abc;// Присваивание полю данных класса A base.f(); // Вызов метода класса А base.g();// Вызов метода класса A } Во внешнем методе : public static void Main (string[] args) { B b = new B(); ((A) b).f(); // Вызов метода класса А ((A) b).g(); // Вызов метода класса B }

Запечатанные (sealed) классы При помощи ключевого слова sealed можно обозначить класс как не предназначенный для наследования: namespace System { public sealed class String {... } Применение ключевого слова sealed позволяет компилятору оптимизировать код. void f(String s) { String s2 = s.Substring(1,10); // Динамический тип } // известен и равен String

Абстрактные классы Во многих случаях виртуальный метод базового класса не выполняет никаких действий. Методы, не имеющие реализации, называют абстрактными. Классы, содержащие абстрактные методы, также называют абстрактными. Абстрактные классы и методы объявляются при помощи ключевого слова abstract. Нельзя создать экземпляр абстрактного класса. Абстрактный класс используется только для создания производных классов. Абстрактные методы задают сигнатуры для определения в производных классах. abstract class Shape { public abstract void Draw();... } class Rectangle : Shape { public override void Draw() {... }... } class Polygon : Shape { public override void Draw() {... }... }

Особенности работы с абстрактными классами abstract class Shape { public abstract void Draw();... } class Rectangle : Shape { public override void Draw() {... }... } Абстрактный метод всегда является виртуальным. Абстрактный класс может не содержать абстрактных методов. Абстрактный класс может иметь конструкторы. Абстрактный метод должен обязательно содержаться в абстрактном классе.

Преобразование типов struct S { … } class C { …} … S s = new S(); C c = new C(); object o = s; // Неявное преобразование C c2 = (S)c; // Ошибка на этапе компиляции o = c; // Неявное преобразование c2 = (C)o; // Правильное явное преобразование o = 5; // Неявное преобразование s = (S)o; // Исключение InvalidCastException Объект производного класса всегда может быть неявно преобразован к базовому классу. Для преобразования базового класса к производному требуется явное приведение типов. Неверное приведение типа может быть определено на этапе компиляции или на этапе выполнения программы. В последнем случае возникает исключение InvalidCastException

Операторы as и is class Bs { … } class Dr : Bs { … } … object obj = 5; bool res1 = obj is int; // true res1 = obj is string; // false obj = new Dr(); res1 = obj is Bs; // true res1 = obj is Dr; // true Оператор is позволяет проверить, является ли динамический тип первого операнда совместимым с типом - вторым операндом. Оператор as позволяет выполнять преобразование типов без возникновения исключения. Если преобразование не может быть выполнено, то результат оператора as равен null. class Bs { … } class Dr : Bs { … } … object obj = new Dr(); Bs b = obj as Bs; // b != null Dr d = obj as Dr; // d != null string s = obj as string; // s == null