24/05/2018, 20:16

Tính kế thừa-3

Mặc dù một đối tượng lớp dẫn xuất cũng là một đối tượng lớp cơ sở, kiểu lớp dẫn xuất và kiểu lớp cơ sở thì khác nhau. Các đối tượng lớp dẫn xuất có thể được xử lý như các đối tượng lớp cơ sở. Điều này có ý nghĩa bởi vì lớp dẫn xuất có các ...

Mặc dù một đối tượng lớp dẫn xuất cũng là một đối tượng lớp cơ sở, kiểu lớp dẫn xuất và kiểu lớp cơ sở thì khác nhau. Các đối tượng lớp dẫn xuất có thể được xử lý như các đối tượng lớp cơ sở. Điều này có ý nghĩa bởi vì lớp dẫn xuất có các thành viên tương ứng với mỗi thành viên của lớp cơ sở. Phép gán theo chiều hướng ngược lại là không cho phép bởi vì gán một đối tượng lớp cơ sở cho đối tượng lớp dẫn xuất sẽ cho phép thêm các thành viên lớp dẫn xuất không xác định.

Một con trỏ trỏ tới một đối tượng lớp dẫn xuất có thể được chuyển đổi ngầm định thành một con trỏ trỏ tới một đối tượng lớp cơ sở bởi vì một đối tượng lớp dẫn xuất là một đối tượng lớp cơ sở.

Có bốn cách để trộn và đối sánh các con trỏ lớp cơ sở và các con trỏ lớp dẫn xuất với các đối tượng lớp cơ sở và các đối tượng lớp dẫn xuất:

Tham chiếu tới một đối tượng lớp cơ sở với một con trỏ lớp cơ sở thì không phức tạp.

Tham chiếu tới một đối tượng lớp dẫn xuất với một con trỏ lớp dẫn xuất thì không phức tạp.

Tham chiếu tới đối tượng lớp dẫn xuất với một con trỏ lớp cơ sở thì an toàn bởi vì đối tượng lớp dẫn xuất cũng là một đối tượng lớp cơ sở của nó. Như vậy đoạn mã chỉ có thể tham chiếu tới các thành viên lớp cơ sở. Nếu đoạn mã tham chiếu tới các thành viên lớp dẫn xuất thông qua con trỏ lớp cơ sở, trình biên dịch sẽ báo một lỗi về cú pháp.

Tham chiếu tới một đối tượng lớp cơ sở với một con trỏ lớp dẫn xuất thì có lỗi cú pháp. Đầu tiên con trỏ lớp dẫn xuất phải được ép sang con trỏ lớp cơ sở.

Chúng ta sẽ xem xét một phân cấp các lớp Point, Circle, Cylinder như hình 5.9

Hình 5.9

Ví dụ 5.5: Lớp Point và project có tên là CT5_5.PRJ (gồm các file POINT.CPP, CT5_5.CPP).

File POINT.H:

POINT.H1: //POINT.H2: //Định nghĩa lớp Point3: #ifndef POINT_H4: #define POINT_H5:6: class Point7: {8: protected:9: float X,Y;10: public:11: Point(float A = 0, float B = 0);12: void SetPoint(float A, float B);13: float GetX() const14: {15: return X;16: }17: float GetY() const18: {19: return Y;20: }21: friend ostream & operator <<(ostream &Output, const Point &P);22: };23:24: #endif

File POINT.CPP

POINT.CPP1: //POINT.CPP2: //Định nghĩa các hàm thành viên của lớp Point3: #include <iostream.h>4: #include "point.h"5:6: Point::Point(float A, float B)7: {8: SetPoint(A, B);9: }10:11: void Point::SetPoint(float A, float B)12: {13: X = A;14: Y = B;15: }16:17: ostream & operator <<(ostream &Output, const Point &P)18: {19: Output << '[' << P.X << ", " << P.Y << ']';20: return Output;21: }

File CT5_5.CPP:

CT5_5.CPP1: //CT5_5.CPP2: //Chương trình 5.53: #include <iostream.h>4: #include "point.h"5: 6: int main()7: {8: Point P(7.2, 11.5);9: cout << "X coordinate is " << P.GetX()10:            << endl << "Y coordinate is " << P.GetY();11: P.SetPoint(10, 10);12: cout << endl << endl << "The new location of P is "<< P << endl;14: return 0;15: }

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

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

Ví dụ 5.6: Lớp Circle và project có tên là CT5_6.PRJ (gồm các file POINT.CPP, CIRCLE.CPP, CT5_6.CPP).

File CIRCLE.H:

CIRCLE.H1: //CIRCLE.H2: //Định nghĩa lớp Circle3: #ifndef CIRCLE_H4: #define CIRCLE_H5:6: #include "point.h"7:8: class Circle : public Point9: {10: protected:11: float Radius;12: public:13: Circle(float R = 0.0, float A = 0, float B = 0);14: void SetRadius(float R);15: float GetRadius() const;16: float Area() const;17: friend ostream & operator <<(ostream &Output, const Circle &C);18: };19:20: #endif

File CIRCLE.CPP

CIRCLE.CPP1: //CIRCLE.CPP2: //Định nghĩa các hàm thành viên của lớp Circle3: #include <iostream.h>4: #include <iomanip.h>5: #include "circle.h"6:7: Circle::Circle(float R, float A, float B) : Point(A, B)8: {9: Radius = R;10: }11: 12: void Circle::SetRadius(float R)13: {14: Radius = R;15: }16:17: float Circle::GetRadius() const18: {19: return Radius;20: }21:22: float Circle::Area() const23: {24: return 3.14159 * Radius * Radius;25: }26:27: //Xuất một Circle theo dạng: Center = [X, Y]; Radius = #.##28: ostream & operator <<(ostream &Output, const Circle &C)29: {30: Output << "Center = [" << C.X << ", " << C.Y31: << "]; Radius = " << setiosflags(ios::showpoint)32: << setprecision(2) << C.Radius;33: return Output;34: }

File CT5_6.CPP

CT5_6.CPP1: //CT5_6.CPP2: //Chương trình 5.63: #include <iostream.h>4: #include "point.h"5: #include "circle.h"6:7: int main()8: {9: Circle C(2.5, 3.7, 4.3);10: cout << "X coordinate is " << C.GetX()11:            << endl << "Y coordinate is " << C.GetY()12:            << endl << "Radius is " << C.GetRadius();13: C.SetRadius(4.25);14: C.SetPoint(2, 2);15: cout << endl << endl << "The new location and radius of C are"16:            << endl << C << endl << "Area " << C.Area() << endl;17: Point &PRef = C;18: cout << endl << "Circle printed as a Point is: "19:            << PRef << endl;20: return 0;21: }

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

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

Ví dụ 5.7: Lớp Cylinder và project có tên là CT5_7.PRJ (gồm các file POINT.CPP, CIRCLE.CPP, CYLINDR.CPP, CT5_7.CPP).

File CYLINDR.H

CYLINDR.H1: //CYLINDR.H2: //Định nghĩa lớp Cylinder3: #ifndef CYLINDR_H4: #define CYLINDR_H5: 6: #include "circle.h"7:8: class Cylinder : public Circle9: {10: protected:11: float Height;12: public:13: Cylinder(float H = 0.0, float R = 0.0, float A = 0.0, float B = 0.0);14: void SetHeight(float);15: float GetHeight() const;16: float Area() const;17: float Volume() const;18: friend ostream & operator <<(ostream &Output, const Cylinder &C);19: };20:21: #endif

File CYLINDR.CPP

CYLINDR.CPP1: //CYLINDR.CPP2: //Định nghĩa các hàm thành viên lớp Cylinder3: #include <iostream.h>4: #include <iomanip.h>5: #include "cylindr.h"6:7: Cylinder::Cylinder(float H, float R, float A, float B) : Circle(R, A, B)8: {9: Height = H;10: }11:12: void Cylinder::SetHeight(float H)13: {14: Height = H;15: }16:17: float Cylinder::GetHeight() const18: {19: return Height;20: }21:22: //Tính diện tích của Cylinder (diện tích mặt)23: float Cylinder::Area() const24: {25: return 2*Circle::Area()+2 * 3.14159*Radius*Height;26: }27:28: float Cylinder::Volume() const29: {30: return Circle::Area() * Height;31: }32:33: ostream & operator <<(ostream &Output, const Cylinder& C)34: {35: Output << "Center = [" << C.X << ", " << C.Y36: << "]; Radius = " << setiosflags(ios::showpoint)37: << setprecision(2) << C.Radius38: << "; Height = " << C.Height;39: return Output;40: }

File CT5_7.CPP

CT5_7.CPP1: //CT5_7.CPP2: //Chương trình 5.73: #include <iostream.h>4: #include <iomanip.h>5: #include "point.h"6: #include "circle.h"7: #include "cylindr.h"8: int main()9: {10: Cylinder Cyl(5.7, 2.5, 1.2, 2.3);11: cout << "X coordinate is " << Cyl.GetX() << endl12:            << "Ycoordinate is " << Cyl.GetY() << endl13:            << "Radius is " << Cyl.GetRadius() << endl14:            << "Height is " << Cyl.GetHeight() << endl << endl ;15: Cyl.SetHeight(10);16: Cyl.SetRadius(4.25);17: Cyl.SetPoint(2, 2);18: cout << "The new location, radius, "19:      << "and height of Cyl are:" << endl << Cyl << endl;20: Point &PRef = Cyl;21: cout << endl << "Cylinder printed as a Point is: "22:      << PRef << endl << endl;23: Circle &cRef = Cyl;24: cout << "Cylinder printed as a Circle is:" << endl << cRef25:            << endl << "Area: " << cRef.Area() << endl;26: return 0;27: }

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

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

0