2013
Курс по програмиране на C#
Занятие №9
Наследяване. Видимост и капсулиране
Съдържание
• Наследяване
• Наследяване в C#
• Превръщане на типове нагоре и надолу по йерархията
• Видимост
• Капсулиране
Наследяване
• Какво е „наследяване“?
– Основен принцип в ООП
– Един клас може да наследи характеристиките и поведението на...
Наследяване
• Примери за наследяване
– Жив организъм <- Бактерия, Растение, Животно, Гъба
– Животно <- Риба, Земноводно, В...
Наследяване
• Защо е полезно наследяването?
– Категоризирането на обекти в практиката става на различни нива
– Служи за по...
Наследяване
• Принципи на действие на наследяването
– Родителският клас описва набор от характеристики и поведение,
присъщ...
Наследяване в C#
• Деклариране на наследени класове
– В декларацията на клас може да се укаже родителски клас, който
той н...
Наследяване в C#
// Родителски клас - произволно животно
class Animal
{
public string Species;
public int Weight;
public i...
Деклариране на наследен клас - демо
// Демонстрация
Наследяване в C#
• Употреба на членовете на родителски клас
– В декларацията на наследен клас могат да бъдат достъпвани
чл...
Наследяване в C#
class Animal
{
//...
public string GetDescription()
{
return string.Format(
"Species: {0}; Age: {1}",
Spe...
Употреба на членовете на родителски клас - демо
// Демонстрация
Наследяване в C#
• Конструктори на наследени класове
– При деклариране на конструктор в наследен клас може да се
укаже кой...
Наследяване в C#
class Animal
{
//...
public Animal() { }
public Animal(string species)
{
Species = species;
}
}
class Dog...
Конструктори на наследени класове - демо
// Демонстрация
Превръщане на типове нагоре и надолу по
йерархията
• Променливи и екземпляри на класове в паметта
– Не е задължително типъ...
Превръщане на типове нагоре и надолу по
йерархията
• Превръщане на типове нагоре по йерархията (upcasting)
– Нека тип A е ...
Превръщане на типове нагоре и надолу по
йерархията
// Създаване на екземпляр на класа Dog
Dog dog = new Dog("German shephe...
Превръщане на типове нагоре по йерархията - демо
// Демонстрация
Превръщане на типове нагоре и надолу по
йерархията
• Превръщане на типове надолу по йерархията (downcasting)
– Нека тип A ...
Превръщане на типове нагоре и надолу по
йерархията
// Присвояване на екземпляр na класа Dog
// на променлива от тип Animal...
Превръщане на типове надолу по йерархията - демо
// Демонстрация
Превръщане на типове нагоре и надолу по
йерархията
• Проверка за съвместимост на типове
– Нека тип A е част от йерархията ...
Превръщане на типове нагоре и надолу по
йерархията
// Създаване на екземпляр на класа Animal
Animal animal = new Animal(
"...
Проверка за съместимост на типове и безопасно
превръщане на типове надолу по йерархията - демо
// Демонстрация
Видимост
• Какво е „видимост“?
– Понятие в програмирането, служещо за ограничаване на достъпа
до фрагменти от кода
– В ООП...
Видимост
• Видимост в C#
– Модификатори за достъп
– Поставят се в декларациите на типове и членове
– Важат единствено за с...
Видимост
• Модификатори за достъп за членове в C#
– Модификаторът за достъп се поставя в началото на декларацията
на съотв...
Видимост
class MailMessage
{
private string _subject;
protected MailMessage(string subject)
{
_subject = subject;
}
public...
Видимост на членове - демо
// Демонстрация
Видимост
• Модификатори за достъп за типове в C#
– Модификаторът за достъп се поставя в началото на декларацията
на съотве...
Видимост
public class MusicAlbum
{
// ...
}
public enum MusicGenre
{
// ...
}
internal class AlbumCollection
{
// ...
}
in...
Видимост на типове - демо
// Демонстрация
Капсулиране
• Какво е „капсулиране“?
– Основен принцип в ООП
– Всеки обект трябва да скрива от външния свят вътрешната си
...
Капсулиране
• Защо е полезно капсулирането?
– Опростява „външния вид“ на обекта
– Позволява промяна на вътрешната реализац...
Капсулиране
• Принципи на капсулирането
– Всеки член или тип данни трябва да има възможно най-
ограничената видимост, позв...
Капсулиране - демо
// Демонстрация
Задачи за упражнение
• Преработете програмата с геометричните фигури и тела
от упражненията към предишната лекция, така че...
Задачи за упражнение
• Реализирайте приложение за регистриране и разглеждане
на списък с произведения в библиотека със сле...
Задачи за упражнение
• Реализирайте походова конзолна ролева игра:
– Играта се развива в правоъгълна мрежа от символи, под...
Въпроси?
Благодаря!
• Александър Далемски
– sasho@david.bg
– Skype: musasho
– https://facebook.com/adalemski
• ДАВИД академия
– aca...
Upcoming SlideShare
Loading in …5
×

Училищен курс по програмиране на C# (2013/2014), занятие №9

333 views

Published on

Училищен курс по програмиране на C# (2013/2014)
Занятие №9: Наследяване. Видимост и капсулиране

Published in: Education
  • Be the first to comment

  • Be the first to like this

Училищен курс по програмиране на C# (2013/2014), занятие №9

  1. 1. 2013 Курс по програмиране на C# Занятие №9 Наследяване. Видимост и капсулиране
  2. 2. Съдържание • Наследяване • Наследяване в C# • Превръщане на типове нагоре и надолу по йерархията • Видимост • Капсулиране
  3. 3. Наследяване • Какво е „наследяване“? – Основен принцип в ООП – Един клас може да наследи характеристиките и поведението на друг – Родителски клас – по-общ; обхваща по-голямо множество обекти – Наследен клас – по-специализиран; обхваща по-тясно множество обекти, описвайки ги по-подробно – Един родителски клас може да има много наследници – Йерархии от класове – един клас може едновременно да бъде наследен за друг и да бъде родителски за няколко други класа – Някои езици позволяват множествено наследяване (няколко независими родителски класа); C# не е от тях
  4. 4. Наследяване • Примери за наследяване – Жив организъм <- Бактерия, Растение, Животно, Гъба – Животно <- Риба, Земноводно, Влечуго, Птица, Бозайник – Бозайник <- Лъв, Котка, Куче, Примат, Човек – Сграда <- Жилищна сграда, Обществена сграда – Обществена сграда <- Библиотека, Читалище, Училище – Художествено произведение <- Картина, Скулптура, Роман, Мюзикъл – Файл <- Текстов файл, Двоичен файл – Текстов файл <- TXT файл, HTML файл, XML файл – Графичен елемент <- Прозорец, Бутон, Текстово поле, Календар – Бутон <- Обикновен бутон, Радио бутон, Бутон в лента с инструменти
  5. 5. Наследяване • Защо е полезно наследяването? – Категоризирането на обекти в практиката става на различни нива – Служи за по-добро смислово структуриране на кода на програмата – Позволява манипулациите с нехомогенни набори от данни – Прави възможно приложението на алгоритми върху категория от обекти, независимо от пълният им набор от характеристики и поведение
  6. 6. Наследяване • Принципи на действие на наследяването – Родителският клас описва набор от характеристики и поведение, присъщи на всички обекти от него – Наследеният клас автоматично получава всички описани от родителския клас характеристики и поведение, като в допълнение към тях описва други, специфични само за неговите обекти – Всеки екземпляр на наследения клас може автоматично да се разглежда и като екземпляр на родителския клас – Същите принципи важат и в по-сложни йерархии на повече от едно ниво
  7. 7. Наследяване в C# • Деклариране на наследени класове – В декларацията на клас може да се укаже родителски клас, който той наследява – Не може да бъде указан повече от един родителски клас – Родителският клас може от своя страна да наследява трети клас и т.н. – Не може клас да наследява себе си или някой от своите наследници – Ако не се укаже родителски клас, декларираният клас по подразбиране наследява object – Членовете на родителския клас не се декларират повторно в наследения клас; те могат да се използват наготово
  8. 8. Наследяване в C# // Родителски клас - произволно животно class Animal { public string Species; public int Weight; public int Age; public void Vocalize() { } } // Наследен клас – куче class Dog : Animal { public string Breed; public string Name; public void Vocalize() { Console.WriteLine("Woof!"); } } • Деклариране на наследен клас – Ключова дума class – Наименование на класа – Двоеточие – Наименование на родителския клас (частично или пълно) – Блок с декларации на членове – При неуказване на родителски клас, класът по подразбиране наследява object – Разрешено е член на наследения клас да има същото наименование като член на родителския клас (но в общия случай не е желателно)
  9. 9. Деклариране на наследен клас - демо // Демонстрация
  10. 10. Наследяване в C# • Употреба на членовете на родителски клас – В декларацията на наследен клас могат да бъдат достъпвани членовете на родителския клас, все едно са членове на същия клас – Ако наследения клас декларира член със същото име като член на родителския клас, членът на родителския клас може да бъде достъпен чрез представката “base.” – В останалата част от програмата, оперирането с всички членове на обект се извършва по еднотипен начин, независимо в кой клас в йерархията от класове на обекта е деклариран съответният член
  11. 11. Наследяване в C# class Animal { //... public string GetDescription() { return string.Format( "Species: {0}; Age: {1}", Species, Age); } } class Dog : Animal { //... public string GetDescription() { return string.Format( "{0}; Breed: {1}; Name: {2}", base.GetDescription(), Breed, Name); } } • Употреба на членовете на родителски клас в декларацията на наследения клас • Достъпване на членове с припокриващи се имена в декларацията на наследения клас – Ключова дума base – Оператор за достъпване на член . – Наименование на члена • Употреба на членовете на родителски клас в останалата част от програмата
  12. 12. Употреба на членовете на родителски клас - демо // Демонстрация
  13. 13. Наследяване в C# • Конструктори на наследени класове – При деклариране на конструктор в наследен клас може да се укаже кой конструктор на родителския клас да бъде изпълнен, както и аргументите, които да му бъдат подадени – Тези аргументи може да са както константи и литерали, така и параметри на конструктора в наследения клас или по-сложни изрази – Конструкторът на базовия клас се изпълнява преди конструктора на наследения клас – Ако не е указано кой конструктор на родителския клас да бъде изпълнен, по подразбиране се изпълнява конструкторът без параметри
  14. 14. Наследяване в C# class Animal { //... public Animal() { } public Animal(string species) { Species = species; } } class Dog : Animal { //... public Dog() : base("Canis lupus familiaris") { } public Dog(string breed) { Species = "Canis lupus familiaris"; Breed = breed; } } • Конструктори на наследени класове - изпълнение на конструктор на родителския клас – Модификатор за видимост – Наименование – Списък с параметри – Двоеточие – Ключова дума base – Списък с аргументи на родителския конструктор – Тяло на конструктора • Изпълнение на конструктор по подразбиране
  15. 15. Конструктори на наследени класове - демо // Демонстрация
  16. 16. Превръщане на типове нагоре и надолу по йерархията • Променливи и екземпляри на класове в паметта – Не е задължително типът на променлива и типът на обекта в паметта, който тази променлива реферира, да съвпадат – Разрешено е променлива от тип A да реферира обект от тип B, ако типът А е част от йерархията от родителски типове на типа B (казваме, че тип B е съвместим с тип A) – В противен случай се предизвиква грешка (при компилация или по време на изпълнение)
  17. 17. Превръщане на типове нагоре и надолу по йерархията • Превръщане на типове нагоре по йерархията (upcasting) – Нека тип A е част от йерархията от родителски типове на тип B – Присвоява се на променлива от тип A израз от тип B – Друг вариант: израз от тип B участва в по-сложен израз в ролята на израз от тип A – Не е необходим специален синтаксис (неявно превръщане на типове) – Винаги е разрешено и не може да предизвика грешка – Типът на обекта в паметта не се променя – Следствие: на променлива от тип object може да бъде присвоен произволен израз
  18. 18. Превръщане на типове нагоре и надолу по йерархията // Създаване на екземпляр на класа Dog Dog dog = new Dog("German shepherd"); // Превръщане на типове нагоре по // йерархията към родителския клас Animal Animal animal = dog; // Превръщане на типове нагоре по // йерархията в сложен израз ((Animal)dog).Vocalize(); • Присвояване на израз от наследен тип на променлива от родителски тип • Сложни изрази с превръщане на типове нагоре по йерархията
  19. 19. Превръщане на типове нагоре по йерархията - демо // Демонстрация
  20. 20. Превръщане на типове нагоре и надолу по йерархията • Превръщане на типове надолу по йерархията (downcasting) – Нека тип A е част от йерархията от родителски типове на тип B – Присвоява се на променлива от тип B израз от тип A – Друг вариант: израз от тип A участва в по-сложен израз в ролята на израз от тип B – Необходимо е явно превръщане на типове – В случай че типът на обекта в паметта не е съвместим с типа B, се предизвиква грешка – Компилаторът не разрешава преобразуване между типове, които се намират в различни клонове от йерархията (тъй като това води до сигурна грешка при изпълнение)
  21. 21. Превръщане на типове нагоре и надолу по йерархията // Присвояване на екземпляр na класа Dog // на променлива от тип Animal Animal animal = new Dog("Poodle"); // Превръщане на типове надолу по // йерархията към наследения клас Dog Dog dog = (Dog)animal; // Превръщане на типове надолу по // йерархията в сложен израз Console.WriteLine(((Dog)animal).Breed); • Присвояване на израз от родителски тип на променлива от наследен тип – Тип, към който ще бъде извършено превръщането, заграден в кръгли скоби – Израз, който трябва бъде превърнат в указания тип • Сложни изрази с превръщане на типове надолу по йерархията
  22. 22. Превръщане на типове надолу по йерархията - демо // Демонстрация
  23. 23. Превръщане на типове нагоре и надолу по йерархията • Проверка за съвместимост на типове – Нека тип A е част от йерархията от родителски типове на тип B – С оператора is може да се провери дали обектът в паметта, рефериран от израз от тип A, е съвместим с типа B – Ако операторът is върне стойност истина, превръщането на типове надолу по йерархията е безопасно – Операторът as може да се използва за безопасно превръщане надолу по йерархията; в случай че типовете са несъвместими, резултатът от превръщането е null – Операторът as може да се използва единствено за превръщане надолу по йерархията към референтен тип
  24. 24. Превръщане на типове нагоре и надолу по йерархията // Създаване на екземпляр на класа Animal Animal animal = new Animal( "Felis silvestris catus"); // Проверка за съвместимост на типове за // безопасно превръщане на типове надолу // по йерархията с is if (animal is Dog) { Console.WriteLine( ((Dog)animal).Breed); } // Безопасно превръщане на типове надолу // по йерархията с as Dog dog = animal as Dog; if (dog != null) Console.WriteLine(dog.Breed); • Проверка за съместимост на типове с is – Израз, чиято стойност трябва да бъде проверена за съвместимост – Оператор is – Тип, съвместимостта с който трябва да бъде проверена • Безопасно превръщане на типове надолу по йерархията с as – Израз, чиято стойност трябва да бъде превърната към друг тип – Оператор as – Референтен тип, към който трябва да бъде извършено безопасното превръщане
  25. 25. Проверка за съместимост на типове и безопасно превръщане на типове надолу по йерархията - демо // Демонстрация
  26. 26. Видимост • Какво е „видимост“? – Понятие в програмирането, служещо за ограничаване на достъпа до фрагменти от кода – В ООП – видимост на членове и видимост на типове – Видимостта на член ограничава достъпа до съответния член от различни участъци от програмата (същия клас, наследени класове, други класове в същия модул, други модули) – Видимостта на тип ограничава достъпа до съответния тип от различни участъци от програмата (същия модул, друг модул)
  27. 27. Видимост • Видимост в C# – Модификатори за достъп – Поставят се в декларациите на типове и членове – Важат единствено за съответния тип/член – Ако модификатор за достъп не е указан, по подразбиране видимостта е минималната възможна
  28. 28. Видимост • Модификатори за достъп за членове в C# – Модификаторът за достъп се поставя в началото на декларацията на съответния член – private – членът е достъпен единствено в рамките на декларация на същия клас (това е видимостта по подразбиране) – protected – членът е достъпен в рамките на декларацията на същия клас и всички негови наследени класове – public – членът е достъпен навсякъде в програмата – internal – членът е достъпен навсякъде в рамките на същото асембли – internal protected – членът е достъпен навсякъде в рамките на същото асембли, както и в декларациите на всички наследени класове, независимо в кое асембли са декларирани
  29. 29. Видимост class MailMessage { private string _subject; protected MailMessage(string subject) { _subject = subject; } public string GetSubject() { return _subject; } internal void Send() { // ... } } • Видимост на членове – Членове, достъпни единствено за същия клас – Членове, достъпни за същия клас и наследените от него класове – Членове, достъпни за цялата програма – Членове, достъпни в същото асембли
  30. 30. Видимост на членове - демо // Демонстрация
  31. 31. Видимост • Модификатори за достъп за типове в C# – Модификаторът за достъп се поставя в началото на декларацията на съответния тип (клас, структура, изброен тип и др.) – public – типът е достъпен навсякъде в програмата – internal – типът е достъпен в рамките на същото асембли (това е видимостта по подразбиране)
  32. 32. Видимост public class MusicAlbum { // ... } public enum MusicGenre { // ... } internal class AlbumCollection { // ... } internal struct UserInfo { // ... } • Видимост на типове – Типове, достъпни за цялата програма – Типове, достъпни в същото асембли
  33. 33. Видимост на типове - демо // Демонстрация
  34. 34. Капсулиране • Какво е „капсулиране“? – Основен принцип в ООП – Всеки обект трябва да скрива от външния свят вътрешната си реализация – Видими за останалата част от програмата са само важните за нея характеристики и поведение на обектите
  35. 35. Капсулиране • Защо е полезно капсулирането? – Опростява „външния вид“ на обекта – Позволява промяна на вътрешната реализация на обекта, без да се налага промяна в останалата част от програмата – Осигурява интегритет на вътрешните характеристики на обекта
  36. 36. Капсулиране • Принципи на капсулирането – Всеки член или тип данни трябва да има възможно най- ограничената видимост, позволяваща смисленото реализиране на програмата – Характеристиките на обекта са достъпни само за самия клас – Методите, реализиращи вътрешно поведение, също са достъпни само за самия клас – Външен достъп до характеристиките на обекта може да се осъществи само чрез други членове на класа (методи – аксесори и мутатори; конструктори; свойства; индексатори) – Възможно е наследените класове да имат привилегирован достъп до някои членове на родителския клас, но само за тези, които са им нужни
  37. 37. Капсулиране - демо // Демонстрация
  38. 38. Задачи за упражнение • Преработете програмата с геометричните фигури и тела от упражненията към предишната лекция, така че да се възползвате от принципите за наследяване и капсулиране: – Капсулирайте данните на всички обекти: всички полета да бъдат частни и промяната на стойностите им да се извършва през конструктори и методи (публични или защитени) – Създайте базови класове Object2D (характеристики: периметър и лице) и Object3D (характеристики: обем и пълна повърхнина) и реализирайте изчисляването им на базата на специфичните характеристики наследени класове – Създайте колекции от базовите класове и реализирайте логика за въвеждане/извеждане на характеристиките им (използвайки upcasting и downcasting)
  39. 39. Задачи за упражнение • Реализирайте приложение за регистриране и разглеждане на списък с произведения в библиотека със следните класове: – Печатно произведение (заглавие; език; издателство) • Периодично печатно произведение (година; брой) – Вестник (вид: ежедневник, седмичник, двуседмичник; гл. редактор; водеща новина за броя) – Списание (тема; авторски колектив; описание на корицата на броя) • Самостоятелно печатно произведение (дата на издаване; автор/автори; брой страници) – Научна статия (научна област; препоръчана литература) – Книга (номер на изданието; твърди/меки корици; наличие на илюстрации) » Художествена литаратура (жанр; целева аудитория) » Техническа литература (научна област; ниво на аудиторията: начинаещи, напреднали, експерти)
  40. 40. Задачи за упражнение • Реализирайте походова конзолна ролева игра: – Играта се развива в правоъгълна мрежа от символи, подобно на Златотърсачи – Създайте базов клас за единица (играч или чудовище), който съдържа информация за координатите на единицата, точките живот и нанасяните от единицата щети – Създайте наследени класове за играч и различни видове чудовища – В началото на играта, поставете играча и известен брой чудовища в игралното поле – Реализирайте безкраен цикъл, в който всяка единица получава ход, в който може да се придвижва или атакува противник, отнемайки му точки живот; чудовищата управлявайте програмно – Бонус: добавете случаен елемент в играта (например случайно количество щети при нападение, случайно генериран терен на игралното поле, и/или различни характеристики за чудовища от един и същи вид) – Бонус: добавете екипировка за играча 
  41. 41. Въпроси?
  42. 42. Благодаря! • Александър Далемски – sasho@david.bg – Skype: musasho – https://facebook.com/adalemski • ДАВИД академия – acad@david.bg – http://acad.david.bg/ – @david_academy – https://facebook.com/DavidAcademy

×