Доступ до елементів класу з екземплярів класів, що утворюють ієрархію. Особливості застосування посилання на базовий клас. Ключові слова as, is. Способи виклику методів з однаковими іменами в ієрархіях успадкування. Статичний поліморфізм
У даній темі вивчається:
- доступ з допомогою екземплярів до елементів класів, які утворюють ієрархію;
- доступ до з допомогою посилання на базовий клас до елементів класів, що утворюють ієрархію;
- вивчення особливостей використання ключових слів is, as;
- способи виклику методів, які мають однакові імена в ієрархії класів.
Зміст
- 1. Використання екземплярів класів, що утворюють ієрархію. Особливості доступу до елементів базового класу з екземпляру успадкованого класу
- 2. Приклад, що демонструє доступ з екземплярів класів, що утворюють ієрархію
- 3. Посилання на базовий клас в ієрархії класів. Особливості застосування
- 4. Приклад, що демонструє обмеження, які можуть виникнути при використанні посилання на базовий клас
- 5. Способи організації доступу до елементів похідного класу з допомогою посилання на базовий клас. Ключові слова is, as
- 6. Приклад, що демонструє способи організації доступу за посиланням до елементів похідного класу. Статичний поліморфізм
- Зв’язані теми
Пошук на інших ресурсах:
1. Використання екземплярів класів, що утворюють ієрархію. Особливості доступу до елементів базового класу з екземпляру успадкованого класу
Якщо класи утворюють ієрархію успадкування, то можна оголошувати об’єкти (екземпляри) кожного з класів ієрархії. Виключення стосується тільки абстрактних класів та інтерфейсів, екземпляри яких неможливо оголосити.
Якщо оголошено екземпляри різних класів, то з допомогою цих екземплярів можна отримати доступ до public-елементів цих класів. Якщо деякий клас є успадкованим з іншого класу, то з екземпляру цього класу можна отримати доступ:
- до усіх public-елементів даного класу;
- до тих public-елементів базового класу, імена яких не “ховаються” (перекриваються) елементами даного класу.
З екземпляру класу неможливо отримати доступу до елементів класів, успадкованих від даного.
Рисунок 1 демонструє доступ з екземплярів objA, objB, objC класів A, B, C що утворюють ієрархію успадкування. З кожного екземпляру робиться спроба викликати методи його класу та методи інших класів ієрархії.
Рисунок 1. Доступ до елементів класів з екземплярів цих класів
⇑
2. Приклад, що демонструє доступ з екземплярів класів, що утворюють ієрархію
Нижче наводиться текст демонстраційної програми яка відповідає рисунку 1. Програма створена за шаблоном Console Application.
using System; using static System.Console; namespace C_sharp { // Клас A - базовий клас class A { public void Show() { WriteLine("Method A.Show()"); } public void ShowA() { WriteLine("Method A.ShowA()"); } } // Клас B - успадкований клас від класу A class B : A { public new void Show() { WriteLine("Method B.Show()"); } public void ShowB() { WriteLine("Method B.ShowB()"); } } // Клас C - успадкований з класу B class C : B { public new void Show() { WriteLine("Method C.Show()"); } public void ShowC() { WriteLine("Method C.ShowC()"); } } class Program { static void Main(string[] args) { // 1. Екземпляри (об'єкти) класів A, B, C A objA = new A(); B objB = new B(); C objC = new C(); // 2. Доступ до елементів з допомогою objA objA.Show(); // викликається A.Show() objA.ShowA(); // викликаєтья A.ShowA() // objA.ShowB(); - помилка, немає доступу: базовий клас не може // розширитись до можливостей похідного // objA.showC(); - помилка, також немає доступу WriteLine("-------------------"); // 3. Доступ до елементів з об'єкту objB класу B objB.Show(); // за замовчуванням викликається B.Show(), тому що // метод B.Show() ховає (перекриває) метод A.Show() objB.ShowA(); // виклик методу базового класу A.ShowA() objB.ShowB(); // B.ShowB() // objB.ShowC(); - помилка, немає доступу: базовий клас не може // розширитись до можливостей похідного класу WriteLine("-------------------"); // 4. Доступ до елементів з об'єкту objC класу C objC.Show(); // C.Show() - даний метод перекриває методи базових класів objC.ShowA(); // A.ShowA() objC.ShowB(); // B.ShowB() objC.ShowC(); // C.ShowC() } } }
Результат виконання програми
Method A.Show() Method A.ShowA() ------------------- Method B.Show() Method A.ShowA() Method B.ShowB() ------------------- Method C.Show() Method A.ShowA() Method B.ShowB() Method C.ShowC()
⇑
3. Посилання на базовий клас в ієрархії класів. Особливості застосування
Як відомо, на будь-який клас може бути оголошене посилання. Якщо класи утворюють ієрархію успадкування, то для цих класів можна визначити наступне правило (правило 1): посиланню на базовий клас можна присвоїти значення екземпляру (об’єкту) похідного класу.
Тобто, після того як оголошене посилання на базовий клас, цьому посиланню можна присвоювати значення об’єкту (екземпляру) будь-якого класу з ієрархії. Таким чином, можна “рухатись” з допомогою посилання по створеним екземплярам класів з ієрархії.
Рисунок 2 демонструє правило 1 на прикладі ієрархії з 3 класів A, B, C.
Рисунок 2. Присвоєння посиланню на базовий клас значень екземплярів похідних класів
Після того, як посиланню на базовий клас присвоєно значення одного з екземплярів класу з ієрархії, можна спробувати використовувати елементи цього екземпляру (викликати методи, властивості, тощо). У цьому випадку доречним є правило 2: якщо посилання на базовий клас отримує значення об’єкту (екземпляру) похідного класу, то доступ за цим посиланням є тільки до елементів базового класу. Рисунок 3 демонструє використання правила 2.
Рисунок 3. Демонстрація доступу до елементів класів A, B з допомогою посилання rA на базовий клас A
Як видно з рисунку 2, з допомогою посилання на базовий клас можна доступитись до елементів базового класу A. До елементів успадкованого класу B немає доступу. Щоб організувати доступ до елементів успадкованого класу B потрібно використовувати способи приведення типу A до типу B (дивіться пункт 5).
⇑
4. Приклад, що демонструє обмеження, які можуть виникнути при використанні посилання на базовий клас
У прикладі продемонстровано обмеження доступу до елементів екземпляру objB похідного класу B з посилання rA на базовий клас A. Неможливо викликати елементи класу B без явного приведення типу та використання операторів is, as.
using System; using static System.Console; namespace C_sharp { // Клас A - базовий клас class A { public void Show() { WriteLine("Method A.Show()"); } public void ShowA() { WriteLine("Method A.ShowA()"); } } // Клас B - успадкований клас від класу A class B : A { public void Show() { WriteLine("Method B.Show()"); } public void ShowB() { WriteLine("Method B.ShowB()"); } } class Program { static void Main(string[] args) { // 1. Посилання на базовий клас A rA; // 2. Екземпляр класу A A objA = new A(); // 3. Екземпляр класу B B objB = new B(); // 4. Посиланню базового класу можна присвоювати // значення посилання базового класу - це зрозуміло rA = objA; // 5. Використання елементів за посиланням rA.Show(); // викликається A.Show() rA.ShowA(); // A.ShowA() // rA.ShowB(); // - помилка, немає доступу до ShowB() // 6. Посиланню базового класу можна присвоювати // значення посилання похідного класу (правило 1) rA = objB; // rA посилається на екземпляр objB класу B rA.Show(); // знову викликається A.Show() - важливо rA.ShowA(); // A.ShowA() // rA.ShowB(); // помилка, знову немає доступу до ShowB() // щоб викликати B.Show() потрібно здійснити приведення // посилання rA до типу B явним чином. } } }
Результат виконання програми
Method A.Show() Method A.ShowA() Method A.Show() Method A.ShowA()
⇑
5. Способи організації доступу до елементів похідного класу з допомогою посилання на базовий клас. Ключові слова is, as
Як було визначено у попередньому пункті, якщо посилання на базовий клас посилається на екземпляр похідного класу, то з допомогою цього посилання існує доступ тільки до елементів базового класу. Однак, це правило можна змінити і отримати доступ до елементів похідних класів.
Щоб з допомогою посилання на базовий клас отримати доступ елементу похідного класу, потрібно використати один з трьох можливих способів.
- використати явне приведення до типу успадкованого класу;
- використати ключове слово as, яке здійснює спробу приведення одного типу до іншого;
- використати ключове слово as у поєднанні з перевіркою на сумісність типів. Перевірка на сумісність використовує ключове слово is.
На рисунку 4 зображено усі 3 способи для заданих класів A, B які утворюють ієрархію.
Рисунок 4. Доступ до елементів похідного класу з допомогою посилання на базовий клас
⇑
6. Приклад, що демонструє способи організації доступу за посиланням до елементів похідного класу. Статичний поліморфізм
У прикладі демонструється 3 способи організації доступу до методу Show() похідного класу B з посилання на базовий клас A. Реалізовані способи демонструють статичний поліморфізм, коли централізований виклик методу формується на етапі компіляції (під час приведення типу).
using System; using static System.Console; namespace C_sharp { // Клас A - базовий клас class A { public void Show() { WriteLine("Method A.Show()"); } public void ShowA() { WriteLine("Method A.ShowA()"); } } // Клас B - успадкований від класу A class B : A { public new void Show() { WriteLine("Method B.Show()"); } public void ShowB() { WriteLine("Method B.ShowB()"); } } class Program { static void Main(string[] args) { // 1. Посилання на базовий клас A rA; // 2. Екземпляр класу A A objA = new A(); // 3. Екземпляр класу B B objB = new B(); // 4. Доступ до екземпляру базового класу A rA = objA; rA.Show(); // викликається A.Show() rA.ShowA(); // A.ShowA() // rA.ShowB(); - помилка, немає доступу // 5. Доступ до елементів екземпляру objB // з допомогою посилання на A rA = objB; // rA посилається на objB // 5.1. Спосіб №1. Приведення до типу B - необхідно, // щоб виклик rA.Show() => objB.Show(). try { // rA привести до типу B ((B)rA).Show(); // викликається B.Show() } catch { // Якщо приведення rA до типу B не відбулось, то вихід WriteLine("Error."); return; } // 5.2. Спосіб №2. Використання ключового слова as. // Ключове слово as використовується у випадках, // коли потрібно здійснити спробу приведення // одного типу до іншого. rA = objB; if ((rA as B) != null) (rA as B).Show(); // B.Show() // 5.3. Спосіб №3. Використання поєднання ключових слів is, as. // Ключове слово is використовується для визначення // сумісності двох типів. Якщо типи сумісні, то результат // рівний true, інакше false. if (rA is B) (rA as B).Show(); // B.Show() } } }
⇑
Зв’язані теми
- Спадковість. Основні поняття. Переваги та недоліки. Загальна форма. Найпростіші приклади. Модифікатор доступу protected
- Приклад доступу до методів та властивостей успадкованих класів з допомогою посилання на базовий клас
⇑