Наследование. Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся.

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



Advertisements
Похожие презентации
Полиморфизм. Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Advertisements

Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float.
Наследование Полиморфизм ВЫЗОВ КОНСТРУКТОРОВ И ДЕСТРУКТОРОВ ПРИ НАСЛЕДОВАНИИ.
Множественное наследование class A {... }; class B {... }; class C : public A, protected B {... }; !!! Спецификатор доступа распространяется только на.
Объектно-ориентированное программирование С++. Лекция 6 Карпов В.Э.
1 Классы в Java Ключевое слово class означает: Я говорю тебе, как выглядит новый тип объекта. Класс является базовым элементом объектно-ориентированного.
Кафедра ОСУ, Java 2004 Слайд 1 Наследование Наследование позволяет использовать существующий класс для определения новых классов, т.е. способствует.
Лекция 4. Введение в С++ Наследование, множественное наследование. Конструкторы, деструкторы. Виртуальные функции.
Лекция 2: Описание класса 1. Поля 2. Методы 3. Конструкторы.
Введение в объектно- ориентированное программирование.
Полиморфизм Полиморфизм (polymorphism) - последний из трех "китов", на которых держится объектно-ориентированное программирование Слово это можно перевести.
1 Java 6. ИНТЕРФЕЙСЫ И ВНУТРЕННИЕ КЛАССЫ. 2 Интерфейсы Не являются классами Ни один из объявленных методов не может быть реализован внутри интерфейса.
Производные классы Определение класса посредством добавления возможностей к уже имеющемуся классу без перепрограммирования или перекомпиляции самого класса.
ОБЪЕКТНО- ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ (ООП) 1.
Интерфейсы Лекция 4. Реализуйте очередь в виде списка, содержащую комплексные числа Реализуйте методы void Enqueue(Complex с ) – помещает число в очередь.
Лекция 8. Введение в ООП. Часть 1 Красс Александр СПбГУ ИТМО, 2008.
Прикладное программирование кафедра прикладной и компьютерной оптики Наследование.
Основы ООП и C# Работа с объектами и классами. Классы Класс специальный тип данных для описания объектов. Он определяет данные и поведение типа. Определение.
НаследованиеНаследование2 class Point { double x; double y; Color color; }; class Radius { Point center; double radius; };
Транксрипт:

Наследование

Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым или родительским. Новый класс – потомком, наследником или производным классом. Наследование является одним из трех основополагающих принципов ООП. Поскольку оно допускает создание иерархических классификаций. Благодаря наследованию можно создать общий класс, в котором определяются характерные особенности, присущие множеству связанных элементов. От этого класса могут затем наследовать другие, более конкретные классы, добавляя в него свои индивидуальные особенности. В языке C# класс, который наследуется, называется базовым, а класс, который наследует, производным. Следовательно, производный класс представляет собой специализированный вариант базового класса. Он наследует все переменные, методы, свойства и индексаторы, определяемые в базовом классе, добавляя к ним свои собственные элементы.

Основы наследования Поддержка наследования в C# состоит в том, что в объявление одного класса разрешается вводить другой класс. Для этого при объявлении производного класса указывается базовый класс. При описании класса имя его предка записывается в заго-ловке класса после двоеточия: [атрибуты][спецификаторы] class [:предки] { } Если имя предка не указано, предком считается базовый класс всей иерархии System.Object. Элементы базового класса, определенные как private, в производном классе недоступны. Поля, определенные со спецификатором protected, будут доступны методам всех классов, производных от базового. Для отображения иерархии наследования используется диаграмма классов.

Пример. Создадим класс для определения двухмерных фигур типа, прямоугольник, квадрат, ромб и.т.д. с параметрами высота и ширина и методом для вывода этих значений. Опишем производный класс – треугольника, содержащий методы расчета площади и вывода типа треугольника(прямоугольный, равнобедренный и т.п.) Диаграмма классов Figura2D Pl

Несмотря на то что класс Figura2D является базовым для класса Triangle, в то же время он представляет собой совершенно независимый и самодостаточный класс. Если класс служит базовым для производного класса, то это совсем не означает, что он не может быть использован самостоятельно. Для любого производного класса можно указать только один базовый класс. В C# не предусмотрено наследование нескольких базовых классов в одном производном классе.

Тем не менее можно создать иерархию наследования, в которой производный класс становится базовым для другого производного класса. (Разумеется, ни один из классов не может быть базовым для самого себя как непосредственно, так и косвенно.) Но в любом случае производный класс наследует все члены своего базового класса, в том числе переменные экземпляра, методы, свойства и индексаторы. Главное преимущество наследования заключается в следующем: как только будет создан базовый класс, в котором определены общие для множества объектов атрибуты, он может быть использован для создания любого числа более конкретных производных классов.

Пример. Добавим еще один класс наследник класса Figura2D и инкапсулирующий прямоугольники, содержащий два метода - определения площади и проверки на квадрат.

Доступ к членам класса и наследование Члены класса зачастую объявляются закрытыми, чтобы исключить их несанкционированное или незаконное использование. Но наследование класса не отменяет ограничения, накладываемые на доступ к закрытым членам класса. Поэтому если в производный класс и входят все члены его базового класса, в нем все равно оказываются недоступными те члены базового класса, которые являются закрытыми. Закрытый член класса остается закрытым в своем классе. Он не доступен из кода за пределами своего класса, включая и производные классы. Для преодоления данного ограничения в C# предусмотрены разные способы. Один из них состоит в использовании защищенных (protected) членов класса, рассматриваемых далее, а второй в применении открытых свойств для доступа к закрытым данным.

Организация защищенного доступа Защищенный член является открытым в пределах иерархии классов, но закрытым за пределами этой иерархии. Защищенный член создается с помощью модификатора доступа protected. Если член класса объявляется как protected, он становится закрытым, но за исключением одного случая, когда защищенный член наследуется. В этом случае защищенный член базового класса становится защищенным членом производного класса, а значит, доступным для производного класса. Таким образом, используя модификатор доступа protected, можно создать члены класса, являющиеся закрытыми для своего класса, но все же наследуемыми и доступными для производного класса. Несмотря на всю свою полезность, защищенный доступ пригоден далеко не для всех ситуаций. Модификатор доступа protected следует применять в том случае, если требуется создать член класса, доступный для всей иерархии классов, но для остального кода он должен быть закрытым. А для управления доступом к значению члена класса лучше воспользоваться свойством.

using System; class В { protected int i, j; // члены, закрытые для класса В, // но доступные для класса D public void Set(int a, int b) { i = a; j = b; } public void Show() { Console.WriteLine(i + " " + j); } } class D : В { int k; // закрытый член // члены i и j класса В доступны для класса D public void Setk() { k = i * j; } public void Showk() { Console.WriteLine(k); } } class ProtectedDemo { static void Main() { D ob = new D(); ob.Set(2, 3); // допустимо, поскольку доступно для класса D ob.Show(); // допустимо, поскольку доступно для класса D ob.Setk(); // допустимо, поскольку входит в класс D ob.Showk(); // допустимо, поскольку входит в класс D }

Конструкторы и наследование В иерархии классов допускается, чтобы у базовых и производных классов были свои собственные конструкторы. Конструктор базового класса конструирует базовую часть объекта, а конструктор производного класса производную часть этого объекта. Если конструктор определен только в производном классе, то все происходит очень просто: конструируется объект производного класса, а базовая часть объекта автоматически конструируется его конструктором, используемым по умолчанию. Пример. Добавим в базовый класс свойства для полей для организации защищенного доступа, а в производный конструктор для поля Style.

Наследование и сокрытие имен В производном классе можно определить член с таким же именем, как и у члена его базового класса. В этом случае член базового класса скрывается в производном классе. И хотя формально в C# это не считается ошибкой, компилятор все же выдаст сообщение, предупреждающее о том, что имя скрывается. Если член базового класса требуется скрыть намеренно, то перед его именем следует указать ключевое слово new, чтобы избежать появления подобного предупреждающего сообщения. Следует, однако, иметь в виду, что это совершенно отдельное применение ключевого слова new, не похожее на его применение при создании экземпляра объекта.

// Пример сокрытия имени с наследственной связью. using System; class А { public int i = 0; } // Создать производный класс. class В : А { new int i; // этот член скрывает член i из класса А public В (int b) { i = b; // член i в классе В } public void Show() { Console.WriteLine("Член i в производном классе: " + i); } class NameHiding { static void Main() { В ob = new В(2); ob.Show(); } В этой строке компилятору, по существу, сообщается о том, что вновь создаваемая переменная i намеренно скрывает переменную i из базового класса А и что автору программы об этом известно. Если же опустить ключевое слово new в этой строке кода, то компилятор выдаст предупреждающее сообщение. Вот к какому результату приводит выполнение приведенного выше кода. Член i в производном классе: 2 В классе В определяется собственная переменная экземпляра i, которая скрывает переменную i из базового класса А. Поэтому при вызове метода Show() для объекта типа В выводится значение переменной i, определенной в классе В, а не той, что определена в классе А.

Применение ключевого слова base для доступа к скрытому имени Имеется еще одна форма ключевого слова base, которая действует подобно ключевому слову this, за исключением того, что она всегда ссылается на базовый класс в том производном классе, в котором она используется. Ниже эта форма приведена в общем виде: base.переменная где переменная может обозначать метод или переменную экземпляра. Эта форма ключевого слова base чаще всего применяется в тех случаях, когда под именами членов производного класса скрываются члены базового класса с теми же самыми именами.

// Применение ключевого слова base для преодоления // препятствия, связанного с сокрытием имен. using System; class А { public int i = 0; } // Создать производный класс. class В : А { new int i; // этот член скрывает член i из класса А public В(int a, int b) { base.i = а; // здесь обнаруживается скрытый член из класса А i = b; // член i из класса В } public void Show() { // Здесь выводится член i из класса А. Console.WriteLine("Член i в базовом классе: " + base.i); // А здесь выводится член i из класса В. Console.WriteLine("Член i в производном классе: " + i); } class UncoverName { static void Main() { В ob = new В(1, 2); ob.Show(); } Выполнение этого кода приводит к следующему результату. Член i в базовом классе: 1 Член i в производном классе: 2 using System; class А { public int i = 0; // Метод Show() в классе A public void Show() { Console.WriteLine("Член i в базовом классе: " + i); } // Создать производный класс. class В : А { new int i; // этот член скрывает член i из класса А public В(int a, int b) { base.i = а; // здесь обнаруживается скрытый член из класса А i = b; // член i из класса В } // Здесь скрывается метод Show() из класса А. Обратите // внимание на применение ключевого слова new. new public void Show() { base.Show(); // здесь вызывается метод Show() из класса А // далее выводится член i из класса В Console.WriteLine("Член i в производном классе: " + i); } class UncoverName { static void Main() { В ob = new В(1, 2); ob.Show(); } Выполнение этого кода приводит к следующему результату. Член i в базовом классе: 1 Член i в производном классе: 2

Создание многоуровневой иерархии классов В C# можно также строить иерархии, состоящие из любого числа уровней наследования. Как упоминалось выше, многоуровневая иерархия идеально подходит для использования одного производного класса в качестве базового для другого производного класса. Так, если имеются при класса, А, В и С, то класс С может наследовать от класса В, а тот, в свою очередь, от класса А. В таком случае каждый производный класс наследует характерные особенности всех своих базовых классов. В частности, класс С наследует все члены классов В и А. Пример. Добавим производный класс ColorTriangle, который будет наследовать классу Triangle и будет содержать поля r,g,b – для описания цвета в палитре RGB.