Phạm Vi Truy Xuất Các Thành Phần Của Lớp Cơ Sở


- Hình ảnh của lớp dẫn xuất B:

Hình . Minh họa sự kế thừa của lớp dẫn xuất

Kế thừa từ lớp A

Thành phần bổ sung của lớp B

B

GV: Để SV có thể hiểu rõ hơn bản chất của sự kế thừa đơn, GV sử dụng các vẽ hình minh họa từng thành phần trong lớp dẫn xuất nhằm phát triển khả năng tường minh hóa cấu trúc của lớp cho SV như sau:


GV? Trong bài học trước, các bạn đã được biết phạm vi tác dụng của các thành phần trong một lớp. Vậy dựa vào đâu để xác định được phạm vi tác dụng của các thành phần đó trong một lớp?

SV trả lời, GV hỏi rõ tác dụng cụ thể của từng loại phạm vi như public, private và protected. Sau đó, GV tiếp tục gợi mở vấn đề với phạm vi “protected” có gì cần chú ý khi sử dụng sự kế thừa trong lớp.


2.2 Thành phần được bảo vệ (protected)

- Ý nghĩa: cho phép các lớp kế thừa được truy xuất nhưng bên ngoài lớp thì không được truy xuất.


GV xét một ví dụ minh họa phạm vi tác dụng của thành phần sau từ khóa protected. Để hiểu rõ hơn GV cho SV phân tích từng câu lệnh trong đoạn chương trình sau.


GV? Trong ví dụ sau, phân tích kết quả từng câu lệnh gán trong hàm main( ) như thế nào?

- Thành phần được khai báo sau từ khóa protected :

Ví dụ:

class A

{

private :

int x ; protected :

int y ; public :

int z ;

} ;

void main ( )

{ A t ;

t. x = 5 ; // sai vì x chỉ được thao tác trong phạm vi lớp

t. y = 5 ; // sai vì y được bảo vệ

t. z = 5 ; // đúng

}


GV: Tương tự như phạm vi tác dụng của các thành phần trong lớp, trong sự kế thừa của các lớp, cũng phải có phạm vi truy xuất của các thành phần của lớp cơ sở như thế nào cũng tùy thuộc vào các từ khóa được khai báo.


2.3 Phạm vi truy xuất các thành phần của lớp cơ sở

- Tất cả các thành phần của lớp cơ sở đều được kế thừa cho lớp dẫn xuất nhưng có thể không được phép truy xuất.

- Những thành phần private ở lớp cơ sở không được truy xuất trong lớp dẫn xuất nhưng các thành phần public, protected được truy xuất.


GV xét một ví dụ minh họa phạm vi truy xuất của thành phần khi sử dụng từ khóa dẫn xuất là public. Để hiểu rõ hơn GV cho SV phân tích từng câu lệnh trong đoạn chương trình sau.

GV? Trong ví dụ sau, phân tích kết quả từng câu lệnh gán trong hàm main( ) như thế nào khi áp dụng kế thừa theo kiểu dẫn xuất public?



Ví dụ:

Lớp A: class A

{ private :

int x ; protected :

int y ; public :

int z ;

} ;

Lớp dẫn xuất B:

class B : public A

{ void setX ( int xx ) { x = xx ;} // sai vì x ở private void setY ( int yy ) { y = yy ;} // đúng vì y ở protected void setX ( int zz ) { z = zz ;} // đúng vì y ở public

} ;

GV lưu ý cho SV về hàm bạn khi kế thừa.



* Nhận xét:

- Hàm bạn (friend) ở lớp cơ sở được truy xuất mọi thành phần của nó nhưng lớp dẫn xuất (lớp con, lớp cháu) chỉ được truy xuất ở public, protected.


2.4 Các kiểu dẫn xuất

- Ý nghĩa: dùng để quyết định các thành phần kế thừa nằm ở phạm vi nào của lớp dẫn xuất.

- Bảng tổng hợp về sự quyết định các thành phần kế thừa nằm ở phạm

vi trong lớp dẫn xuất:

Bảng 2. . Bảng ý nghĩa các kiểu dẫn xuất thể hiện trong sự kế thừa

GV: Trong sự kế thừa, kiểu dẫn xuất chiếm vai trò quan trọng quyết định phạm vi tác dụng của các thành phần trong lớp dẫn xuất cũng như lớp cơ sở. Do vậy, có thể tổng hợp trong bảng sau:



Lớp cơ sở

Kiểu dẫn xuất

Lớp dẫn xuất

public

protected private


public

public

protected không truy xuất

public

protected private


protected

protected

protected không truy xuất

public protected

private


private

private Private

không truy xuất

Có thể bạn quan tâm!

Xem toàn bộ 235 trang tài liệu này.

Dạy học kĩ thuật lập trình cho sinh viên ngành Kĩ thuật điện tử - viễn thông theo hướng phát triển tư duy điện toán - 24



2.5 Định nghĩa lại các thành phần

- Các thành phần kế thừa từ lớp cơ sở có thể được định nghĩa lại (trùng tên) trong lớp dẫn xuất. Khi đó, trong lớp dẫn xuất tồn tại hai thành phần trùng tên, do đó, thành phần kế thừa phải dùng toán tử phạm vi.

- Ký hiệu toán tử phạm vi: ::



Ví dụ minh họa việc định nghĩa lại các thành phần: Cho một lớp HV

lớp HCN kế thừa từ lớp HV. Ta cần định nghĩa lại các thành phần là phương thức nhap( ), dt( ) của lớp HCN. Cụ thể viết như sau:

class HV

{ protected :

int c ;

public :

void nhap( ) ;

int dt( ) { return c * c ; }

} ;

void HV :: nhap( )

{ cout << “Nhap canh: ” ; cin >> c ;

}

class HCN : public HV

{ protected :

int cc ; public :

void nhap( ) ;

int dt( ) { return c * cc ; } } ;



void HCN :: nhap( )

{ cout << “Nhap canh thu nhat: ” ; cin >> c ;

cout << “Nhap canh thu hai: ” ; cin >> cc ;

}

void main( )

HV :: nhap( )

{ HV h1 ; HCN h2 ;

h1. nhap( ) ; // HV :: nhap( )

cout << “Dien tich hinh vuong h1 = ” << h1. dt() ; h2. nhap( ) ; // HCN :: nhap( )

cout << “Dien tich hinh vuong h1 = ” << h2. dt() ;

}



Cách viết khác:

class HV

{ private :

int c ;

public :

void nhap( ) ;

int dt( ) { return c * c ; }

int getc( ) { return c ; } // hàm đọc giá trị biến c,

chứ không tham chiếu vào c

} ;


void HV :: nhap( )

{ cout << “Nhap canh: ” ; cin >> c ;

}

class HCN : public HV

{ protected :

int cc ; public :

void nhap( ) ;

int dt( ) { return getc( ) * cc ; }

} ;

void HCN :: nhap( )

{ cout << “Nhap canh thu nhat: ” ; cin >> c ;

cout << “Nhap canh thu hai: ” ; cin >> cc ;

}

void main( )

HV :: nhap( )

{ HV h1 ; HCN h2 ;

h1. nhap( ) ; // HV :: nhap( )

cout << “Dien tich hinh vuong h1 = ” << h1. dt() ; h2. nhap( ) ; // HCN :: nhap( )

cout << “Dien tich hinh vuong h1 = ” << h2. dt() ;

}


* Lưu ý:

- Với biến h2 thuộc lớp kế thừa HCN, muốn gọi hàm nhap( ) kế thừa từ lớp NV ta viết: h2. HV :: nhap( ) ;

- Việc định nghĩa lại các thành phần trong lớp kế thừa và phép chồng hàm là khác nhau.


2.6 Cấu tử và hủy tử trong lớp dẫn xuất

- Hủy tử của lớp cơ sở sẽ tự động thực hiện ngay sau khi thực hiện hủy tử của lớp dẫn xuất.

Ví dụ:

class A

{ … public :

~A( ) { cout << “~A” ; }

} ;

class B : public A

{ … public :

~B( ) { cout << “~B” ; }

} ;

Void main( )

{

B t ;

}

Kết quả hiện ra màn hình: ~B~A


- Cấu tử ngầm định (không có tham số) của lớp cơ sở sẽ tự động thực hiện khi có một đối tượng của lớp dẫn xuất được hình thành.

Ví dụ:

class A

{ protected :

int x ; public :

A( ) { x = 5 ; }

A( int xx ) { x = xx ; }

void print( ) { cout << “x= ” << x ; }

} ;

class B : public A

{ protected :

int y ; public :

B( ) { y = 7 ; }

B( int yy ) { y = yy ; }

B( int xx , int yy ) { y = yy ; }

void print( ) { A :: print( ) ;

cout << “y= ” << y ; }

} ;

void main( )

{ B O1 , O2( 10 ) , O3 ( 1, 9 ) ;

O1. print( ) ;

O2. print( ) ;

O3. print( ) ;

}


Kết quả hiện ra màn hình:

x = 5

y = 7


x = 5

y = 10


x = 5

y = 9

Xem toàn bộ nội dung bài viết ᛨ

..... Xem trang tiếp theo?
⇦ Trang trước - Trang tiếp theo ⇨

Ngày đăng: 02/09/2022