<< Chapter < Page Chapter >> Page >

Lớp trừu tượng (abstract class)

Trong quá trình thiết kế chương trình theo hướng đối tượng, để tạo nên một hệ thống phả hệ mang tính kế thừa cao, người lập trình phải đoán trước sự phát triển của cấu trúc, từ đó chọn lựa những thành viên phù hợp cho các lớp ở trên cùng. Rõ ràng đây là một công việc vô cùng khó khăn. Để tránh tình trạng người lập trình xây dựng các đối tượng lãng phí bộ nhớ, ngôn ngữ C++ cho phép chúng ta thiết kế các lớp có các không phương thức ảo không làm gì cả, và cũng không thể tạo ra đối tượng thuộc lớp đó. Những lớp như vậy gọi là lớp trừu tượng.

Trong cấu trúc trên hình 6.3, không phải lớp nào cũng thực sự cần đến phương thức Print(), nhưng nó có mặt khắp nơi để tạo ra bộ mặt chung cho mọi lớp trong cấu trúc cây. Phương thức của lớp trên cùng như A::Print() thường là phương thức ảo để có được tính đa hình.

Hình 6.3

Nhờ đó, với hàm sau:

void Show(A* a)

{

a->Print();

}

chúng ta có thể truyền đối tượng đủ kiểu cho nó (A, B, C, D hoặc E) mà vẫn gọi đến đúng phuơng thức Print() phù hợp dù kiểu của đối tượng lúc biên dịch vẫn còn chưa biết. Với vai trò "lót đường" như vậy, phương thức A::Print() có thể chẳng có nội dung gì cả

class A

{

public:

virtual void Print()

{

}

};

Khi đó người ta gọi phương thức A::Print() là phương thức ảo rỗng (null virtual function), nó chẳng làm gì hết. Tuy nhiên lớp A vẫn là một lớp bình thường, chúng ta có thể tạo ra một đối tượng thuộc nó, có thể truy cập tới phương thức A::Print(). Để tránh trình trạng vô tình tạo ra đối tượng thuộc lớp này, người ta thường xây dựng lớp trừu tượng, trình biên dịch cho phép tạo ra lớp có các phương thức thuần ảo (pure virtual function) như sau:

class A

{

public:

virtual void Print() = 0;

};

Phương thức ảo Print() bây giờ là phương thức thuần ảo – phương thức có tên được gán bởi giá trị zero. Lớp A chứa phương thức thuần ảo được gọi là lớp trừu tượng.

Ví dụ 6.3:

1: //Chương trình 6.3

2: #include<iostream.h>

3:

4: class A

5: {

6: public:

7: virtual void Print()=0; //Phương thức thuần ảo

8: };

9:

10: class B : public A

11: {

12: public:

13: virtual void Print()

14: {

15: cout<<"Class B"<<endl;

16: }

17: };

18:

19: class C : public B

20: {

21: public:

22: virtual void Print()

23: {

24: cout<<"Class C"<<endl;

25: }

26: };

27:

28: void Show(A *a)

29: {

30: a->Print();

31: }

32:

33: int main()

34: {

35: B *b=new B;

36: C *c=new C;

37: Show(b); //B::Print()

38: Show(c); //C::Print()

39: return 0;

40: }

Chúng ta chạy ví dụ 6.3 , kết quả ở hình 6.4

Hình 6.4: Kết quả của ví dụ 6.3

Lớp A được tạo ra để làm cơ sở cho việc hình thành các lớp con cháu (B và C). Nhờ có Phương thức ảo Print() từ lớp A cho tới lớp C, tính đa hình được thể hiện.

Lưu ý:

Chúng ta không thể tạo ra một đối tượng của lớp trừu tượng, nhưng hoàn toàn có thể tạo ra một con trỏ trỏ đến lớp này (vì con trỏ không phải là đối tượng thuộc lớp) hoặc là một tham chiếu.

Nếu trong lớp kế thừa từ lớp trừu tượng chúng ta không định nghĩa phương thức thuần ảo, do tính kế thừa nó sẽ bao hàm phương thức thuần ảo của lớp cơ sở, nên lớp dẫn xuất này sẽ trở thành lớp trừu tượng.

Theo định nghĩa lớp trừu tượng, nếu trong lớp dẫn xuất (từ lớp cơ sở trừu tượng) chúng ta định nghĩa thêm một phương thức thuần ảo khác, lớp này cũng sẽ trở thành lớp trừu tượng.

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Lập trình hướng đối tượng. OpenStax CNX. Jul 29, 2009 Download for free at http://cnx.org/content/col10794/1.1
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Lập trình hướng đối tượng' conversation and receive update notifications?

Ask