Tải bản đầy đủ (.docx) (5 trang)

Chương 6 Tương ứng bội và phương thức ảo Phương thức tĩnh

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (64.68 KB, 5 trang )

Phương thức tĩnh
1.1. Lời gọi tới phương thức tĩnh
Như đã biết một lớp dẫn xuất được thừa kế các phương thức của các lớp cơ sở tiền bối của
nó. Ví dụ lớp A là cơ sở của B, lớp B lại là cơ sở của C, thì C có 2 lớp cơ sở tiền bối là B và
A. Lớp C được thừa kế các phương thức của A và B. Các phương thức mà chúng ta vẫn nói là
các phương thức tĩnh. Để tìm hiểu thêm về cách gọi tới các phương thức tĩnh, ta xét ví dụ về
các lớp A, B và C như sau:
class A
{
public:
void xuat()
{
cout << "\n Lop A " ;
}
};
class B:public A
{
public:
void xuat()
{
cout << "\n Lop B " ;
}
};
class C:public B
{
public:
void xuat()
{
cout << "\n Lop C " ;
}
};


Lớp C có 2 lớp cơ sở tiền bối là A , B và C kế thừa các phương thức của A và B. Do đó một
đối tượng của C sẽ có tới 3 phương thức xuat. Hãy theo rõi các câu lệnh sau:
C h ; // h là đối tượng kiểu C
h.xuat() ; // Gọi tới phương thức h.D::xuat()
h.B::xuat() ; // Gọi tới phương thức h.B::xuat()
h.A::xuat() ; // Gọi tới phương thức h.A::xuat()
Các lời gọi phương thức trong ví dụ trên đều xuất phát từ đối tượng h và mọi lời gọi đều xác
định rõ phương thức cần gọi.
317 318
Bây giờ chúng ta hãy xét các lời gọi không phải từ một biến đối tượng mà từ một con trỏ.
Xét các câu lệnh:
A *p, *q, *r; // p, q, r là con trỏ kiểu A
A a; // a là đối tượng kiểu A
B b; // b là đối tượng kiểu B
C c; // c là đối tượng kiểu c
Chúng ta hãy ghi nhớ mệnh đề sau về con trỏ của các lớp dẫn xuất và cơ sở:
Phép gán con trỏ: Con trỏ của lớp cơ sở có thể dùng để chứa địa chỉ các đối tượng của lớp
dẫn xuất.
Như vậy cả 3 phép gán sau đều hợp lệ:
p = &a ;
q = &b ;
r = &c ;
Chúng ta tiếp tục xét các lời gọi phương thức từ các con trỏ p, q, r:
p->xuat();
q->xuat();
r->xuat();
và hãy lý giải xem phương thức nào (trong các phương thức A::xuat, B::xuat và C::xuat) được
gọi. Câu trả lời như sau:
Cả 3 câu lệnh trên đều gọi tới phương thức A::xuat() , vì các con trỏ p, q và r đều có kiểu A.
Như vậy có thể tóm lược cách thức gọi các phương thức tĩnh như sau:

Quy tắc gọi phương thức tĩnh: Lời gọi tới phương thức tĩnh bao giờ cũng xác định rõ
phương thức nào (trong số các phương thức trùng tên của các lớp có quan hệ thừa kế) được
gọi:
1. Nếu lời gọi xuất phát từ một đối tượng của lớp nào, thì phương thức của lớp đó sẽ được
gọi.
2. Nếu lời gọi xuất phát từ một con trỏ kiểu lớp nào, thì phương thức của lớp đó sẽ được
gọi bất kể con trỏ chứa địa chỉ của đối tượng nào.
1.2. Ví dụ
Xét 4 lớp A, B, C và D. Lớp B và C có chung lớp cơ sở A. Lớp D dẫn xuất từ C. Cả 4 lớp
đều có phương thức xuat(). Xét hàm:
void hien(A *p)
{
p->xuat();
}
Không cần biết tới địa chỉ của đối tượng nào sẽ truyền cho đối con trỏ p, lời gọi trong hàm
luôn luôn gọi tới phương thức A::xuat() vì con trỏ p kiểu A. Như vậy bốn câu lệnh:
hien(&a);
hien(&b);
hien(&c);
319 320
hien(&d);
trong hàm main (của chương trình dưới đây) đều gọi tới A::xuat().
//CT6-01
// Phuong thuc tinh
#include <conio.h>
#include <stdio.h>
#include <iostream.h>
#include <ctype.h>
class A
{

private:
int n;
public:
A()
{
n=0;
}
A(int n1)
{
n=n1;
}
void xuat()
{
cout << "\nLop A: "<< n;
}
int getN()
{
return n;
}
};
class B:public A
{
public:
B():A()
{
}
B(int n1):A(n1)
{
}
void xuat()

{
cout << "\nLop B: "<<getN();
}
};
class C:public A
{
public:
C():A()
{
}
C(int n1):A(n1)
{
}
void xuat()
{
cout << "\nLop C: "<<getN();
}
};
class D:public C
{
public:
D():C()
{
}
D(int n1):C(n1)
{
}
void xuat()
{
cout << "\nLop D: "<<getN();

}
};
void hien(A *p)
{
p->xuat();
}
void main()
{
A a(1);
B b(2);
321 322
C c(3);
D d(4);
clrscr();
hien(&a);
hien(&b);
hien(&c);
hien(&d);
getch();
}

×