LỚP TRỪU TƯỢNG (ABSTRACT CLASS)

Một phần của tài liệu gtrinhoop (Trang 125 - 127)

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 đố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; };

126

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 hồn tồ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.

Giáo trình mơn Lập trình hướng đối tượng Trang 127

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.

Một phần của tài liệu gtrinhoop (Trang 125 - 127)

Tải bản đầy đủ (PDF)

(165 trang)