مفهوم و کاربرد کلاس‌های انتزاعی (Abstract Classes) در ++C

Abstract Classes in C Plus Plus

Abstract-Classes-in-cpp

کلاس انتزاعی در C++ چیست؟

گاهی پیاده‌سازی کل تابع، نمی‌تواند در کلاس پایه (base class) صورت بگیرد. چنین کلاسی، کلاس انتزاعی (abstract class) خوانده می‌شود. برای مثال، کلاس شکل (Shape) یک کلاس پایه است. نمی‌توان تابع ()draw را در این کلاس پیاده‌سازی کرد. اما می‌دانیم که هر کلاس مشتق‌شده (derived class) باید تابع ()draw را پیاده‌سازی کند. به طور مشابه، یک کلاس حیوان (Animal class) تابع ()move (فرض کنیم که همه‌ی حیوانات حرکت می‌کنند) پیاده‌سازی نمی‌کند. علاو‌ه بر آن همه‌ی حیوانات باید بدانند چطور حرکت کنند. نمی‌توان از کلاس‌های انتزاعی، شیء (‌objects) ایجاد کرد.

یک تابع مجازی خالص (pure virtual function) یا یک تابع انتزاعی (‌abstract function) در ++C یک تابع مجازی است که می‌توان آن را پیاده‌سازی کرد. اما می‌بایست آن را در کلاس مشتق‌شده به اصطلاح override یا بازنویسی کرد، در غیر این صورت، کلاس مشتق‌شده هم به کلاس انتزاعی تبدیل خواهد شد. یک تابع مجازی با تخصیص مقدار 0 در اعلامیه‌اش، اعلام می‌شود.

مثال زیر را برا درک بهتر این موضوع مشاهده کنید:

// An abstract class
class Test
{   
    // Data members of class
public:
    // Pure Virtual Function
    virtual void show() = 0;
    
   /* Other members */
};

یک مثال کامل از کلاس انتزاعی

یک تابع مجازی خالص (pure virtual function) توسط کلاس‌هایی از یک کلاس انتزاعی (Abstract class) که مشتق‌شده هستند، پیاده‌سازی می‌شود. مثال ساده‌ی زیر، این موضوع را نشان می‌دهد:

#include<iostream>
using namespace std;
  
class Base
{
   int x;
public:
    virtual void fun() = 0;
    int getX() { return x; }
};
  
// This class inherits from Base and implements fun()
class Derived: public Base
{
    int y;
public:
    void fun() { cout << "fun() called"; }
};
  
int main(void)
{
    Derived d;
    d.fun();
    return 0;
}

خروجی قطعه‌کُد بالا به این صورت است:

fun() called

چند حقیقت جالب!

  1. یک کلاس، انتزاعی است که دست‌کم یک تابع مجازی خالص (pure virtual function) داشته باشد.

در مثال زیر، Test یک کلاس انتزاعی است، چرا که یک تابع مجازی به نام ()show دارد.

// pure virtual functions make a class abstract
#include
using namespace std;
class Test
{
int x;
public:
virtual void show() = 0;
int getX() { return x; }
};

int main(void)
{
Test t;
return 0;
}

خروجی قطعه‌کُد بالا به این صورت است:

Compiler Error: cannot declare variable 't' to be of abstract
 type 'Test' because the following virtual functions are pure 
within 'Test': note:     virtual void Test::show()

2. می‌توان از نوع کلاس انتزاعی، اشاره‌گر (‌pointers) و ارجاع (references) داشت. 

مثال زیر، این مورد را نشان می‌دهد:

#include<iostream>
using namespace std;
  
class Base
{
public:
    virtual void show() = 0;
};
  
class Derived: public Base
{
public:
    void show() { cout << "In Derived \n"; }
};
  
int main(void)
{
    Base *bp = new Derived();
    bp->show();
    return 0;
}

3. اگر تابع مجازی خالص (pure virtual function) را در کلاس مشتق‌شده، بازنویسی نکنیم، کلاس مشتق‌شده نیز، به کلاس انتزاعی (abstract class) تبدیل خواهد شد. 

مثال زیر، این موضوع را نشان می‌دهد:

#include<iostream>
using namespace std;
class Base
{
public:
    virtual void show() = 0;
};
  
class Derived : public Base { };
  
int main(void)
{
  Derived d;
  return 0;
}

خروجی قطعه‌کُد بالا به این صورت است:

Compiler Error: cannot declare variable 'd' to be of abstract type 
'Derived'  because the following virtual functions are pure within
'Derived': virtual void Base::show()

4. یک کلاس انتزاعی (abstract class‌) می‌تواند سازنده‌ (constructors) داشته باشد. 

برای مثال، قطعه‌کُد زیر کامپایل و به خوبی اجرا می‌شود:

#include<iostream>
using namespace std;
  
// An abstract class with constructor
class Base
{
protected:
int x;
public:
virtual void fun() = 0;
Base(int i) {
              x = i; 
            cout<<"Constructor of base called\n";
            }
};
  
class Derived: public Base
{
    int y;
public:
    Derived(int i, int j):Base(i) { y = j; }
    void fun() { cout << "x = " << x << ", y = " << y<<'\n'; }
};
  
int main(void)
{ 
    Derived d(4, 5); 
    d.fun();
    
  //object creation using pointer of base class
    Base *ptr=new Derived(6,7);
      ptr->fun();
    return 0;
}

خروجی قطعه‌کُد بالا به این صورت است:

Constructor of base called
x = 4, y = 5
Constructor of base called
x = 6, y = 7

مقایسه با Java

در جاوا، یک کلاس می‌تواند توسط کلمه‌ی کلیدی abstract، به یک کلاس انتزاعی تبدیل شود. به همین صورت، یک تابع هم می‌تواند با استفاده از کلمه‌ی کلیدی abstract به یک تابع مجازی (‌pure virtual) یا انتزاعی (abstract) تبدیل شود. برای جزئیات بیشتر در این مورد، به Abstract Classes in Java رجوع کنید.

رابط (Interface) در مقابل کلاس‌های انتزاعی (‌Abstract Classes)

یک رابط (interface) متُد‌هایش را پیاده‌سازی نمی‌کند، بلکه می‌تواند به عنوان مجموعه‌ای از اعلامیه‌های متُد‌ها در نظر گرفته شود. در ++C، یک رابط را می‌توان با تعریف همه‌ی متُد‌ها به عنوان pure virtual، شبیه‌سازی کرد. در Java، یک کلمه‌کلیدی جدا برای رابط (interface) وجود دارد.

می‌توان رابط (Interface) را به عنوان هِدر‌فایل‌ها در ++C در نظر گرفت، در هِدر‌فایل‌ها فقط بدنه‌ی کلاس را تعریف می‌کنیم که قرار است پیاده‌سازی شود. به طور مشابه در جاوا رابط، تنها بدنه‌ی کلاس را فراهم می‌کند و کُد واقعی را در هر کلاسی که آن را پیاده‌سازی کند، می‌نویسیم.


منبع: وب سایت geeksforgeeks

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.