Відношення між класами типу uses (клас використовує інший клас). Приклади
Дана тема є продовженням теми:
Зміст
- 1. Відношення між класами uses. Класифікація
- 2. Приклад. Клас A використовує ім’я класу B
- 3. Приклад. Клас A використовує клас B
- 4. Приклад. Клас A динамічно створює об’єкт класу B
- 5. Приклад. Клас A отримує розміри класу B
- Зв’язані теми
Пошук на інших ресурсах:
1. Відношення між класами uses. Класифікація
При розробці проектів важливим є визначення того, як клас використовує інші класи. Різні залежності між класами з’являються неявно у мовах програмування.
Згідно з Б.Страуструпом (засновник мови C++) між двома класами A, B можна встановити наступні способи використання класом A класу B:
- Клас A використовує ім’я класу B.
- Клас A використовує клас B.
- Клас A викликає функцію-член класу B.
- Клас A читає поле даних класу B.
- Клас A записує поле даних класу B.
- Клас A створює об’єкт типу B.
- Клас A виділяє пам’ять для автоматичних об’єктів типу B.
- Клас A створює об’єкт типу B з допомогою оператора new.
- Клас A отримує розміри класу B.
⇑
2. Приклад. Клас A використовує ім’я класу B
using System; using static System.Console; namespace ConsoleApp1 { // Взаємодія між класами типу uses // Клас A використовує ім'я класу B // Клас B - базовий клас class B { // Прихована внутрішня змінна private int b = 25; // Віртуальний метод public virtual void Print(B refB) { WriteLine("Method B.Print():"); WriteLine("b = {0}", refB.b); } } // Клас A - похідний від класу B class A : B { // Прихована внутрішня змінна private int a = 15; // У параметрі методу класу A використовується // ім'я класу B, як базового для реалізації поліморфізму public override void Print(B refB) { WriteLine("Method A.Print():"); base.Print(refB); WriteLine("a = {0}", a); } } class Program { static void Main(string[] args) { // 1. Створити екземпляр класу A A objA = new A(); B objB = new B(); // 2. Оголосити посилання на базовий клас B B refB; // 3. Направити посилання refB на екземпляр класу A refB = objA; // 4. Викликати віртуальний метод Print() через посилання refB refB.Print(refB); // викликається objA.Print(refB) // 5. Перенаправити посилання на базовий клас B refB = objB; // 6. Викликати віртуальний метод Print() через посилання refB refB.Print(refB); // викликається objB.Print(refB) } } }
Результат виконання програми
Method A.Print(): Method B.Print(): b = 25 a = 15 Method B.Print(): b = 25
⇑
3. Приклад. Клас A використовує клас B
У прикладі демонструється декілька форм взаємодії між класами, що відноситься до типу uses.
using System; using static System.Console; namespace ConsoleApp1 { // Взаємодія між класами типу uses // Клас A використовує клас B class B { public const double Pi2 = 6.28; public double Pi = 3.14; static public void MethodB() { WriteLine("B.MethodB()"); } } class A { public void MethodA() { // 1. Виклик функції-члена класу B з класу A B.MethodB(); // 2. Звертання до поля даних класу B з класу A WriteLine(B.Pi2); // 3. Запис поля даних класу B B objB = new B(); // створити екземпляр класу B objB.Pi = 3.141592; // записати поле даних } } class Program { static void Main(string[] args) { // 1. Створити екземпляр класу A A objA = new A(); // 2. Викликати метод MethodA() класу A objA.MethodA(); } } }
Результат роботи програми
B.MethodB() 6.28
⇑
4. Приклад. Клас A динамічно створює об’єкт класу B
Даний приклад більш актуальний для мови C++, оскільки у цій мові об’єкт класу в методі можна створити двома способами:
// Мова C++. Спосіб 1 B objB; // Мова C++. Спосіб 2 - з допомогою оператора new B* pB = new B();
У мові C# усі об’єкти (екземпляри) класу створюються динамічно з допомогою оператора new. Це пов’язано з тим, що класи відносяться до типів-посилання а не до типів-значення. У випадку з класами типи-посилання містять посилання на екземпляр класу. Саме посилання розміщується в стеку, а екземпляр розміщується в кучі (heap). Тому, для розміщення екземпляру потрібно виділити пам’ять динамічно.
Текст демонстраційної програми наступний.
using System; using static System.Console; namespace ConsoleApp1 { // Взаємодія між класами типу uses // Клас A динамічно створює об'єкт класу B class B { // Внутрішнє поле public int d; // Метод Show() public void Show() { WriteLine("d = {0}", d); } } class A { // Метод, що динамічно створює об'єкт класу B public void Demo() { WriteLine("Method A.Demo()"); // 1. Створити екземпляр класу B динамічно WriteLine("Creating instance objB."); B objB = new B(); WriteLine("OK!"); // 2. Заповнити значенням об'єкт класу B WriteLine("Fill with values objB.d."); objB.d = 330; WriteLine("OK!"); } } class Program { static void Main(string[] args) { // 1. Створити екземпляр класу A A objA = new A(); // 2. Викликати метод Demo() класу A objA.Demo(); } } }
Результат роботи програми
Method A.Demo() Creating instance objB. OK! Fill with values objB.d. OK!
⇑
5. Приклад. Клас A отримує розміри класу B
У прикладі демонструється визначення розмірів екземпляру класу з допомогою механізму серіалізації.
using System; using static System.Console; // Необхідно для використання можливостей класу Stream using System.IO; // Необхідно для використання класу BinaryFormatter using System.Runtime.Serialization.Formatters.Binary; namespace ConsoleApp1 { // Вихідний клас B, який містить одне поле та один метод // Перед класом вказується, що клас буде зберігатись в пам'яті // (клас, який серіалізується) [Serializable] class B { public double x; void ShowX() { WriteLine("x = {0}", x); } } // Клас A, який містить метод, // що визначає розмір екземпляру класу B class A { // У методі створюється екземпляр класу B, // та визначається його розмір public void DemoSizeObjB() { // 1. Оголосити внутрішні змінні long size = 0; // розмір екземпляру класу B B objB = new B(); // створити екземпляр // 2. Використання потоку в пам'яті у двійковому вигляді // 2.1. Створити потік в пам'яті using (Stream s = new MemoryStream()) { // 2.2. Створити екземпляр бінарного (двійкового) // формату серіалізації BinaryFormatter bf = new BinaryFormatter(); // 2.3. Записати екземпляр objB у двійковому форматі // в пам'ять bf.Serialize(s, objB); // 2.4. Визначити розмір пам'яті, // в який був записаний екземпляр size = s.Length; // 2.5. Вивести розмір на екран WriteLine("size = {0}", size); } } } class Program { static void Main(string[] args) { // 1. Створити екземпляр класу A A objA = new A(); // 2. Викликати метод DemoSizeObjB() objA.DemoSizeObjB(); } } }
Результат роботи програми
size = 129
⇑
Зв’язані теми
- Типи відношень між класами: is-a, has-a, uses. Агрегація. Композиція
- Спадковість. Основні поняття. Переваги та недоліки. Загальна форма. Найпростіші приклади. Модифікатор доступу protected
⇑