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

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров. Абстрактные классы реализуют на практике один из принципов ООП - полиморфизм. Абстрактный класс может содержать (и не содержать[1]) абстрактные методы и свойства. Абстрактный метод не реализуется для класса, в котором описан, однако должен быть реализован для его неабстрактных потомков. Абстрактные классы представляют собой наиболее общие абстракции, то есть имеющие наибольший объем и наименьшее содержание.

В одних языках создавать экземпляры абстрактных классов запрещено, в других это допускается (например, Delphi), но обращение к абстрактному методу объекта этого класса в процессе выполнения программы приведёт к ошибке. Во многих языках допустимо объявить любой класс абстрактным, даже если в нём нет абстрактных методов (например, Java), именно для запрещения создания экземпляров. Абстрактный класс можно рассматривать в качестве интерфейса к семейству классов, порождённому им, но, в отличие от классического интерфейса, абстрактный класс может иметь определённые методы, а также свойства.

Абстрактные методы часто являются и виртуальными, в связи с чем понятия «абстрактный» и «виртуальный» иногда путают.

Содержание

[править] Примеры

[править] 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 << "This object of the class "; }
 
    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 << " call function cb.Abstr();"; } //Подменяющая функция.
    void fun   ( void ){ std::cout << " call function cb.fun()"; }
 
    ~CB () {} // Неверно для абстр. кл. ~CB(){ ~CA(); } 
  };
 
class CC : public CA {
  public:
    CC ( void ) { std::cout << "CC;"; }
 
    void Abstr ( void ) { std::cout << " call function cc.Abstr();"; } //Подменяющая функция.
    void fun   ( void ) { std::cout << " call function cc.fun()"; }
 
  ~CC () {} // Неверно для абстр. кл. ~CC(){ ~CA(); } 
  };
 
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:
This object of the class CB; call function cb.Abstr(); call function cb.fun().
This object of the class CC; call function cc.Abstr(); call function cc.fun().

[править] C#

Модификатор abstract указывает на то, что класс может быть использован только как базовый класс при наследовании. Абстрактные классы могут содержать абстрактные методы и методы доступа. Создавать экземпляры абстрактного класса нельзя. Неабстрактный класс, являющийся производным от абстрактного, должен содержать фактические реализации всех наследуемых абстрактных методов и методов доступа. Чтобы указать отсутствие реализации в методе или свойстве, воспользуйтесь модификатором abstract в объявлении метода или свойства. Абстрактный метод - это неявный виртуальный метод. Объявления абстрактных методов допускаются только в абстрактных классах. Поскольку объявление абстрактного метода не предоставляет фактической реализации, тело метода отсутствует, объявление метода просто заканчивается точкой с запятой, аналогично объявлению прототипов:

public abstract void AbstarctMethod();

Реализация предоставляется методом переопределения override, который является членом неабстрактного класса.

Использование статических или виртуальных модификаторов в объявлении абстрактного метода или свойства является недопустимым. Действие абстрактных свойств аналогично абстрактным методам, за исключением отличий в синтаксисе объявлений и вызовов. Абстрактное унаследованное свойство может быть переопределено в производном классе за счет включения объявления свойства, использующего модификатор переопределения.

    abstract class BaseClass   // Abstract class
    {
        protected int _x = 100;
        protected int _y = 150;
        public abstract void AbstractMethod();   // Abstract method
        public abstract int X    { get; }
        public abstract int Y    { get; }
    }
 
    class DerivedClass : BaseClass
    {
        public override void AbstractMethod()
        {
            _x++;
            _y++;
        }
 
        public override int X   // overriding property
        {
            get
            {
                return _x + 10;
            }
        }
 
        public override int Y   // overriding property
        {
            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 указывает, что класс обязан иметь производные классы.

[править] Примечания

  1. Abstract Methods and Classes (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)

[править] См. также

[править] Литература

  • Подбельский В. В. Глава 10.3 Виртуальные функции и абстрактные классы \\ Абстрактные классы. // Язык Си++ / рец. Дадаев Ю. Г. — 4. — М.: Финансы и статистика, 2003. — С. 365-373. — 560 с. — ISBN 5-279-02204-7, УДК 004.438Си(075.8) ББК 32.973.26-018 1я173.
Личные инструменты
Пространства имён
Варианты
Действия
Навигация
Участие
Печать/экспорт
Инструменты
На других языках