Kế thừa C ++

Một trong những khái niệm quan trọng nhất trong lập trình hướng đối tượng là tính kế thừa. Tính kế thừa cho phép chúng ta xác định một lớp theo nghĩa của một lớp khác, giúp tạo và duy trì một ứng dụng dễ dàng hơn. Điều này cũng tạo cơ hội để sử dụng lại chức năng mã và thời gian thực hiện nhanh chóng.

Khi tạo một lớp, thay vì viết các thành viên dữ liệu hoàn toàn mới và các hàm thành viên, lập trình viên có thể chỉ định rằng lớp mới sẽ kế thừa các thành viên của một lớp hiện có. Lớp hiện có này được gọi làbase lớp và lớp mới được gọi là derived lớp học.

Ý tưởng kế thừa thực hiện is amối quan hệ. Ví dụ, động vật IS-A động vật có vú, chó IS-A động vật có vú, do đó chó IS-A động vật cũng như vậy.

Các lớp cơ sở và có nguồn gốc

Một lớp có thể được dẫn xuất từ ​​nhiều lớp, có nghĩa là nó có thể kế thừa dữ liệu và chức năng từ nhiều lớp cơ sở. Để định nghĩa một lớp dẫn xuất, chúng tôi sử dụng danh sách dẫn xuất lớp để chỉ định (các) lớp cơ sở. Một danh sách dẫn xuất lớp đặt tên cho một hoặc nhiều lớp cơ sở và có dạng:

class derived-class: access-specifier base-class

Nơi chỉ định truy cập là một trong những public, protected, hoặc là private, và lớp cơ sở là tên của một lớp đã được xác định trước đó. Nếu thông số truy cập không được sử dụng, thì nó là riêng tư theo mặc định.

Xem xét một lớp cơ sở Shape và lớp dẫn xuất của nó Rectangle như sau -

#include <iostream>
 
using namespace std;

// Base class
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }
      
   protected:
      int width;
      int height;
};

// Derived class
class Rectangle: public Shape {
   public:
      int getArea() { 
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   return 0;
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

Total area: 35

Kiểm soát truy cập và kế thừa

Một lớp dẫn xuất có thể truy cập tất cả các thành viên không riêng tư của lớp cơ sở của nó. Do đó, các thành viên lớp cơ sở không thể truy cập vào các hàm thành viên của các lớp dẫn xuất nên được khai báo là private trong lớp cơ sở.

Chúng tôi có thể tóm tắt các kiểu truy cập khác nhau theo - ai có thể truy cập chúng theo cách sau -

Truy cập công cộng được bảo vệ riêng tư
Cùng lớp Đúng Đúng Đúng
Các lớp có nguồn gốc Đúng Đúng Không
Các lớp học bên ngoài Đúng Không Không

Một lớp dẫn xuất kế thừa tất cả các phương thức của lớp cơ sở với các ngoại lệ sau:

  • Các hàm tạo, hàm hủy và các hàm tạo sao chép của lớp cơ sở.
  • Các toán tử bị quá tải của lớp cơ sở.
  • Các hàm friend của lớp cơ sở.

Loại thừa kế

Khi dẫn xuất một lớp từ một lớp cơ sở, lớp cơ sở có thể được kế thừa thông qua public, protected hoặc là privatedi sản. Kiểu kế thừa được chỉ định bởi access-specifier như đã giải thích ở trên.

Chúng tôi hầu như không sử dụng protected hoặc là private thừa kế, nhưng publickế thừa được sử dụng phổ biến. Trong khi sử dụng loại kế thừa khác, các quy tắc sau được áp dụng:

  • Public Inheritance - Khi dẫn xuất một lớp từ một public lớp cơ sở, public các thành viên của lớp cơ sở trở thành public các thành viên của lớp dẫn xuất và protected các thành viên của lớp cơ sở trở thành protectedcác thành viên của lớp dẫn xuất. Một lớp cơ sởprivate các thành viên không bao giờ có thể truy cập trực tiếp từ một lớp dẫn xuất, nhưng có thể được truy cập thông qua các lệnh gọi đến publicprotected các thành viên của lớp cơ sở.

  • Protected Inheritance - Khi xuất phát từ một protected lớp cơ sở, publicprotected các thành viên của lớp cơ sở trở thành protected các thành viên của lớp dẫn xuất.

  • Private Inheritance - Khi xuất phát từ một private lớp cơ sở, publicprotected các thành viên của lớp cơ sở trở thành private các thành viên của lớp dẫn xuất.

Nhiều người thừa kế

Một lớp C ++ có thể kế thừa các thành viên từ nhiều hơn một lớp và đây là cú pháp mở rộng:

class derived-class: access baseA, access baseB....

Nơi truy cập là một trong những public, protected, hoặc là privatevà sẽ được cung cấp cho mọi lớp cơ sở và chúng sẽ được phân tách bằng dấu phẩy như hình trên. Hãy để chúng tôi thử ví dụ sau:

#include <iostream>
 
using namespace std;

// Base class Shape
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }
      
   protected:
      int width;
      int height;
};

// Base class PaintCost
class PaintCost {
   public:
      int getCost(int area) {
         return area * 70;
      }
};

// Derived class
class Rectangle: public Shape, public PaintCost {
   public:
      int getArea() {
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;
   int area;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   area = Rect.getArea();
   
   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   // Print the total cost of painting
   cout << "Total paint cost: $" << Rect.getCost(area) << endl;

   return 0;
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

Total area: 35
Total paint cost: $2450