Абстрактний клас

В об'єктно-орієнтованому програмуванні абстрактний клас – це базовий клас, від якого не можна створити екземпляру. На практиці абстрактні класи реалізують один з принципів ООП – поліморфізм. В абстрактному класі можна описати (або не визначити) абстрактні методи та властивості. Абстрактний метод не реалізовується в класі в якому описується, але має бути реалізований в неабстрактному нащадку. Абстрактні класи вважаються найбільшими узагальненими абстракціями, тобто відношення об'єму описів до об'єму реалізації найбільше. В деяких мовах заборонено створювати екземпляри абстрактних класів, в інших дозволяється (наприклад, Delphi), але звернення даного екземпляра, до абстрактного методу викличе помилку. В багатьох мовах дозволяється оголошувати будь-який клас абстрактним навіть, якщо в ньому нема абстрактних методів (наприклад, Java). Для того щоб заборонити створення екземплярів. Абстрактний клас можна розглядати, як інтерфейс для сімейства класів, які ним породжені, але на противагу класичному інтерфейсу, абстрактний клас може містити реалізацію методів та властивості. Абстрактні методи переважно є і віртуальними, через це поняття «абстрактний» та «віртуальний» інколи плутають.

Використання абстрактних класів

Абстрактні класи відіграють важливу роль для статичної типізації в об’єктно-орієнтованих мовах. Багато динамічно типізованих мов не мають схожих механізмів (хоча використання латентної типізації відкидає потребу в абстрактних класах); а ще трейти, реалізацію яких можна знайти в сучасних динамічно типізованих мовах. Деякі програмісти стверджують, що класи повинні бути фінальними (без похідних), або абстрактним.

Абстрактні класи корисні тим, що за їхньою допомогою можна визначити протокол; набір операцій, які мають бути у всіх об'єктах, які реалізують протокол.

Приклад

Java

abstract class Demo {
    // Абстрактний клас може включати абстрактні методи без імплементації.
    abstract public int sum(int x, int y);

    // Абстрактний клас також включає конкретні методи
    public int product(int x, int y) { return x*y; }
}

interface DemoInterface {
    // Всі методи абстрактні.
    int getLength();
}


Delphi

В Delphi можна оголосити абстрактний клас з абстрактними методами.

TAbstractClass = class 
  procedure NonAbstractProcedure;
  procedure AbstractProcedure; abstract;
end;

Від цього класу можна створити екземпляр, але звернення до методу AbstractProcedure даного об'єкту, виведе помилку. В останніх версіях Delphi реалізовано можливість оголошувати сам клас як абстрактний:

TAbstractClass = class abstract
  procedure SomeProcedure;
end;

Хоч метод SomeProcedure може бути реалізований (не абстрактним) в межах даного класу, але створювати екземпляри таких класів заборонено.

C++

Щоб в C++ клас вважався абстрактним у ньому має бути описана щонайменше одна чиста віртуальна функція (це така функція яка не реалізована в даному класі), вигляду virtual __сигнатура методу__ = 0; Яка так як і інші може бути визначена в класах-нащадках. Приклад на мові програмування C++:

#include <iostream>

class CA { // Абстрактний клас
  public:
    CA ( void ) { std::cout << "Це об'єкт класу "; }

    virtual void Abstr ( void ) = 0;
    void         fun   ( void ) { std::cout << "Реалізація не буде наслідуватися!"; }

    ~CA () { std::cout << "." << std::endl; }
  };

class CB : public CA {
  public:
    CB ( void ) { std::cout << "CB;"; }

    void Abstr ( void ){ std::cout << " виклик функції cb.Abstr();"; }
    void fun   ( void ){ std::cout << " виклик функції cb.fun()"; }

    ~CB () {}
  };

class CC : public CA {
  public:
    CC ( void ) { std::cout << "CC;"; }

    void Abstr ( void ) { std::cout << " виклик функції cc.Abstr();"; }
    void fun   ( void ) { std::cout << " виклик функції cc.fun()"; }

  ~CC () {}
  };

int main () {
  std::cout << "Program:" << std::endl;
  CB cb;
  cb.Abstr(); cb.fun(); cb.~CB();

  CC cc;
  cc.Abstr(); cc.fun(); cc.~CC();

  return 0;
  }

Результат роботи програми:

Program:
Це об'єкт класу CB; виклик функції cb.Abstr(); виклик функції cb.fun().
Це об'єкт класу CC; виклик функції cc.Abstr(); виклик функції cc.fun().
.
.

C#

Модифікатор abstract вказує на те, що даний клас можна використовувати тільки як базовий клас для наслідування. Абстрактний клас може містити абстрактні методи та методи доступу. Створювати екземпляр абстрактного класу заборонено через виклик конструктора, але екземпляр абстрактного класу створюється неявно при створені похідного класу від даного абстрактного класу. Неабстрактний клас, який похідний від абстрактного, має містити реальні реалізації всіх абстрактних методів та методів доступу. Щоб вказати про відсутність реалізації метода чи властивості використовуйте модифікатор abstract при їх оголошені. Абстрактний метод – це неявний віртуальний метод. Тільки в абстрактних класах та інтерфейсах (стереотипах, які аналогічні чистим абстрактним класам, в яких відсутня будь-яка реалізація) допускається оголошення абстрактних членів (методів, властивостей, подій). Оскільки оголошення абстрактних методів не надають фактичної реалізації, тіло метода відсутнє, оголошення метода просто завершується крапкою з комою, аналогічно оголошенню прототипів:

public abstract void AbstractMethod();

Реалізація методу створюється шляхом перевизначення override, в неабстрактному класі. Заборонено використовувати статичні чи віртуальні модифікатори при оголошені абстрактних методів або властивостей. Оголошення та реалізація абстрактних властивостей не сильно відрізняються від абстрактних методів, присутні тільки незначні синтаксичні розбіжності в оголошенні і викликах. Абстрактне наслідування властивостей може бути визначені в похідному класі за рахунок включення оголошення властивості з модифікатором перевизначення.

    abstract class BaseClass
    {
        protected int _x = 100;
        protected int _y = 150;
        public abstract void AbstractMethod();
        public abstract int X    { get; }
        public abstract int Y    { get; }
    }

    class DerivedClass : BaseClass
    {
        public override void AbstractMethod()
        {
            _x++;
            _y++;
        }

        public override int X
        {
            get
            {
                return _x + 10;
            }
        }

        public override int Y
        {
            get
            {
                return _y + 10;
            }
        }

        static void Main()
        {
            DerivedClass o = new DerivedClass();
            o.AbstractMethod();
            Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
        }
    }
    // Output: x = 111, y = 161

В абстрактному класі мають бути реалізовані всі члени інтерфейсу. Абстрактний клас, який реалізує інтерфейс, може представляти методи інтерфейсу, як абстрактні методи.

interface I
{
    void M();
}
abstract class C : I
{
    public abstract void M();
}

Абстрактний клас з модифікатор sealed змінювати не можна, оскільки ці два модифікатори мають суперечливі властивості. Модифікатор sealed забороняє наслідування, а abstract обов'язково має мати похідний клас.

Див. також

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.