Upcoming SlideShare
Loading in...5
×
 

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

on

  • 141 views

Училищен курс по програмиране на C# (2013/2014)

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

Statistics

Views

Total Views
141
Views on SlideShare
141
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • 2013 Курс по програмиране на C# Занятие №9 Наследяване. Видимост и капсулиране
  • Съдържание • Наследяване • Наследяване в C# • Превръщане на типове нагоре и надолу по йерархията • Видимост • Капсулиране
  • Наследяване • Какво е „наследяване“? – Основен принцип в ООП – Един клас може да наследи характеристиките и поведението на друг – Родителски клас – по-общ; обхваща по-голямо множество обекти – Наследен клас – по-специализиран; обхваща по-тясно множество обекти, описвайки ги по-подробно – Един родителски клас може да има много наследници – Йерархии от класове – един клас може едновременно да бъде наследен за друг и да бъде родителски за няколко други класа – Някои езици позволяват множествено наследяване (няколко независими родителски класа); C# не е от тях
  • Наследяване • Примери за наследяване – Жив организъм <- Бактерия, Растение, Животно, Гъба – Животно <- Риба, Земноводно, Влечуго, Птица, Бозайник – Бозайник <- Лъв, Котка, Куче, Примат, Човек – Сграда <- Жилищна сграда, Обществена сграда – Обществена сграда <- Библиотека, Читалище, Училище – Художествено произведение <- Картина, Скулптура, Роман, Мюзикъл – Файл <- Текстов файл, Двоичен файл – Текстов файл <- TXT файл, HTML файл, XML файл – Графичен елемент <- Прозорец, Бутон, Текстово поле, Календар – Бутон <- Обикновен бутон, Радио бутон, Бутон в лента с инструменти
  • Наследяване • Защо е полезно наследяването? – Категоризирането на обекти в практиката става на различни нива – Служи за по-добро смислово структуриране на кода на програмата – Позволява манипулациите с нехомогенни набори от данни – Прави възможно приложението на алгоритми върху категория от обекти, независимо от пълният им набор от характеристики и поведение
  • Наследяване • Принципи на действие на наследяването – Родителският клас описва набор от характеристики и поведение, присъщи на всички обекти от него – Наследеният клас автоматично получава всички описани от родителския клас характеристики и поведение, като в допълнение към тях описва други, специфични само за неговите обекти – Всеки екземпляр на наследения клас може автоматично да се разглежда и като екземпляр на родителския клас – Същите принципи важат и в по-сложни йерархии на повече от едно ниво
  • Наследяване в C# • Деклариране на наследени класове – В декларацията на клас може да се укаже родителски клас, който той наследява – Не може да бъде указан повече от един родителски клас – Родителският клас може от своя страна да наследява трети клас и т.н. – Не може клас да наследява себе си или някой от своите наследници – Ако не се укаже родителски клас, декларираният клас по подразбиране наследява object – Членовете на родителския клас не се декларират повторно в наследения клас; те могат да се използват наготово
  • Наследяване в 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 – Разрешено е член на наследения клас да има същото наименование като член на родителския клас (но в общия случай не е желателно)
  • Деклариране на наследен клас - демо // Демонстрация
  • Наследяване в C# • Употреба на членовете на родителски клас – В декларацията на наследен клас могат да бъдат достъпвани членовете на родителския клас, все едно са членове на същия клас – Ако наследения клас декларира член със същото име като член на родителския клас, членът на родителския клас може да бъде достъпен чрез представката “base.” – В останалата част от програмата, оперирането с всички членове на обект се извършва по еднотипен начин, независимо в кой клас в йерархията от класове на обекта е деклариран съответният член
  • Наследяване в 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 – Оператор за достъпване на член . – Наименование на члена • Употреба на членовете на родителски клас в останалата част от програмата
  • Употреба на членовете на родителски клас - демо // Демонстрация
  • Наследяване в C# • Конструктори на наследени класове – При деклариране на конструктор в наследен клас може да се укаже кой конструктор на родителския клас да бъде изпълнен, както и аргументите, които да му бъдат подадени – Тези аргументи може да са както константи и литерали, така и параметри на конструктора в наследения клас или по-сложни изрази – Конструкторът на базовия клас се изпълнява преди конструктора на наследения клас – Ако не е указано кой конструктор на родителския клас да бъде изпълнен, по подразбиране се изпълнява конструкторът без параметри
  • Наследяване в 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 – Списък с аргументи на родителския конструктор – Тяло на конструктора • Изпълнение на конструктор по подразбиране
  • Конструктори на наследени класове - демо // Демонстрация
  • Превръщане на типове нагоре и надолу по йерархията • Променливи и екземпляри на класове в паметта – Не е задължително типът на променлива и типът на обекта в паметта, който тази променлива реферира, да съвпадат – Разрешено е променлива от тип A да реферира обект от тип B, ако типът А е част от йерархията от родителски типове на типа B (казваме, че тип B е съвместим с тип A) – В противен случай се предизвиква грешка (при компилация или по време на изпълнение)
  • Превръщане на типове нагоре и надолу по йерархията • Превръщане на типове нагоре по йерархията (upcasting) – Нека тип A е част от йерархията от родителски типове на тип B – Присвоява се на променлива от тип A израз от тип B – Друг вариант: израз от тип B участва в по-сложен израз в ролята на израз от тип A – Не е необходим специален синтаксис (неявно превръщане на типове) – Винаги е разрешено и не може да предизвика грешка – Типът на обекта в паметта не се променя – Следствие: на променлива от тип object може да бъде присвоен произволен израз
  • Превръщане на типове нагоре и надолу по йерархията // Създаване на екземпляр на класа Dog Dog dog = new Dog("German shepherd"); // Превръщане на типове нагоре по // йерархията към родителския клас Animal Animal animal = dog; // Превръщане на типове нагоре по // йерархията в сложен израз ((Animal)dog).Vocalize(); • Присвояване на израз от наследен тип на променлива от родителски тип • Сложни изрази с превръщане на типове нагоре по йерархията
  • Превръщане на типове нагоре по йерархията - демо // Демонстрация
  • Превръщане на типове нагоре и надолу по йерархията • Превръщане на типове надолу по йерархията (downcasting) – Нека тип A е част от йерархията от родителски типове на тип B – Присвоява се на променлива от тип B израз от тип A – Друг вариант: израз от тип A участва в по-сложен израз в ролята на израз от тип B – Необходимо е явно превръщане на типове – В случай че типът на обекта в паметта не е съвместим с типа B, се предизвиква грешка – Компилаторът не разрешава преобразуване между типове, които се намират в различни клонове от йерархията (тъй като това води до сигурна грешка при изпълнение)
  • Превръщане на типове нагоре и надолу по йерархията // Присвояване на екземпляр na класа Dog // на променлива от тип Animal Animal animal = new Dog("Poodle"); // Превръщане на типове надолу по // йерархията към наследения клас Dog Dog dog = (Dog)animal; // Превръщане на типове надолу по // йерархията в сложен израз Console.WriteLine(((Dog)animal).Breed); • Присвояване на израз от родителски тип на променлива от наследен тип – Тип, към който ще бъде извършено превръщането, заграден в кръгли скоби – Израз, който трябва бъде превърнат в указания тип • Сложни изрази с превръщане на типове надолу по йерархията
  • Превръщане на типове надолу по йерархията - демо // Демонстрация
  • Превръщане на типове нагоре и надолу по йерархията • Проверка за съвместимост на типове – Нека тип A е част от йерархията от родителски типове на тип B – С оператора is може да се провери дали обектът в паметта, рефериран от израз от тип A, е съвместим с типа B – Ако операторът is върне стойност истина, превръщането на типове надолу по йерархията е безопасно – Операторът as може да се използва за безопасно превръщане надолу по йерархията; в случай че типовете са несъвместими, резултатът от превръщането е null – Операторът as може да се използва единствено за превръщане надолу по йерархията към референтен тип
  • Превръщане на типове нагоре и надолу по йерархията // Създаване на екземпляр на класа 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 – Референтен тип, към който трябва да бъде извършено безопасното превръщане
  • Проверка за съместимост на типове и безопасно превръщане на типове надолу по йерархията - демо // Демонстрация
  • Видимост • Какво е „видимост“? – Понятие в програмирането, служещо за ограничаване на достъпа до фрагменти от кода – В ООП – видимост на членове и видимост на типове – Видимостта на член ограничава достъпа до съответния член от различни участъци от програмата (същия клас, наследени класове, други класове в същия модул, други модули) – Видимостта на тип ограничава достъпа до съответния тип от различни участъци от програмата (същия модул, друг модул)
  • Видимост • Видимост в C# – Модификатори за достъп – Поставят се в декларациите на типове и членове – Важат единствено за съответния тип/член – Ако модификатор за достъп не е указан, по подразбиране видимостта е минималната възможна
  • Видимост • Модификатори за достъп за членове в C# – Модификаторът за достъп се поставя в началото на декларацията на съответния член – private – членът е достъпен единствено в рамките на декларация на същия клас (това е видимостта по подразбиране) – protected – членът е достъпен в рамките на декларацията на същия клас и всички негови наследени класове – public – членът е достъпен навсякъде в програмата – internal – членът е достъпен навсякъде в рамките на същото асембли – internal protected – членът е достъпен навсякъде в рамките на същото асембли, както и в декларациите на всички наследени класове, независимо в кое асембли са декларирани
  • Видимост class MailMessage { private string _subject; protected MailMessage(string subject) { _subject = subject; } public string GetSubject() { return _subject; } internal void Send() { // ... } } • Видимост на членове – Членове, достъпни единствено за същия клас – Членове, достъпни за същия клас и наследените от него класове – Членове, достъпни за цялата програма – Членове, достъпни в същото асембли
  • Видимост на членове - демо // Демонстрация
  • Видимост • Модификатори за достъп за типове в C# – Модификаторът за достъп се поставя в началото на декларацията на съответния тип (клас, структура, изброен тип и др.) – public – типът е достъпен навсякъде в програмата – internal – типът е достъпен в рамките на същото асембли (това е видимостта по подразбиране)
  • Видимост public class MusicAlbum { // ... } public enum MusicGenre { // ... } internal class AlbumCollection { // ... } internal struct UserInfo { // ... } • Видимост на типове – Типове, достъпни за цялата програма – Типове, достъпни в същото асембли
  • Видимост на типове - демо // Демонстрация
  • Капсулиране • Какво е „капсулиране“? – Основен принцип в ООП – Всеки обект трябва да скрива от външния свят вътрешната си реализация – Видими за останалата част от програмата са само важните за нея характеристики и поведение на обектите
  • Капсулиране • Защо е полезно капсулирането? – Опростява „външния вид“ на обекта – Позволява промяна на вътрешната реализация на обекта, без да се налага промяна в останалата част от програмата – Осигурява интегритет на вътрешните характеристики на обекта
  • Капсулиране • Принципи на капсулирането – Всеки член или тип данни трябва да има възможно най- ограничената видимост, позволяваща смисленото реализиране на програмата – Характеристиките на обекта са достъпни само за самия клас – Методите, реализиращи вътрешно поведение, също са достъпни само за самия клас – Външен достъп до характеристиките на обекта може да се осъществи само чрез други членове на класа (методи – аксесори и мутатори; конструктори; свойства; индексатори) – Възможно е наследените класове да имат привилегирован достъп до някои членове на родителския клас, но само за тези, които са им нужни
  • Капсулиране - демо // Демонстрация
  • Задачи за упражнение • Преработете програмата с геометричните фигури и тела от упражненията към предишната лекция, така че да се възползвате от принципите за наследяване и капсулиране: – Капсулирайте данните на всички обекти: всички полета да бъдат частни и промяната на стойностите им да се извършва през конструктори и методи (публични или защитени) – Създайте базови класове Object2D (характеристики: периметър и лице) и Object3D (характеристики: обем и пълна повърхнина) и реализирайте изчисляването им на базата на специфичните характеристики наследени класове – Създайте колекции от базовите класове и реализирайте логика за въвеждане/извеждане на характеристиките им (използвайки upcasting и downcasting)
  • Задачи за упражнение • Реализирайте приложение за регистриране и разглеждане на списък с произведения в библиотека със следните класове: – Печатно произведение (заглавие; език; издателство) • Периодично печатно произведение (година; брой) – Вестник (вид: ежедневник, седмичник, двуседмичник; гл. редактор; водеща новина за броя) – Списание (тема; авторски колектив; описание на корицата на броя) • Самостоятелно печатно произведение (дата на издаване; автор/автори; брой страници) – Научна статия (научна област; препоръчана литература) – Книга (номер на изданието; твърди/меки корици; наличие на илюстрации) » Художествена литаратура (жанр; целева аудитория) » Техническа литература (научна област; ниво на аудиторията: начинаещи, напреднали, експерти)
  • Задачи за упражнение • Реализирайте походова конзолна ролева игра: – Играта се развива в правоъгълна мрежа от символи, подобно на Златотърсачи – Създайте базов клас за единица (играч или чудовище), който съдържа информация за координатите на единицата, точките живот и нанасяните от единицата щети – Създайте наследени класове за играч и различни видове чудовища – В началото на играта, поставете играча и известен брой чудовища в игралното поле – Реализирайте безкраен цикъл, в който всяка единица получава ход, в който може да се придвижва или атакува противник, отнемайки му точки живот; чудовищата управлявайте програмно – Бонус: добавете случаен елемент в играта (например случайно количество щети при нападение, случайно генериран терен на игралното поле, и/или различни характеристики за чудовища от един и същи вид) – Бонус: добавете екипировка за играча 
  • Въпроси?
  • Благодаря! • Александър Далемски – sasho@david.bg – Skype: musasho – https://facebook.com/adalemski • ДАВИД академия – acad@david.bg – http://acad.david.bg/ – @david_academy – https://facebook.com/DavidAcademy