Kế thừa đa cấp, phân cấp trong c++

Trong hướng dẫn này, chúng ta sẽ tìm hiểu về các mô hình kế thừa khác nhau trong lập trình C ++: Kế thừa đa cấp, đa cấp và phân cấp với các ví dụ.

Tính kế thừa là một trong những tính năng cốt lõi của ngôn ngữ lập trình hướng đối tượng. Nó cho phép các nhà phát triển phần mềm lấy ra một lớp mới từ lớp hiện có. Lớp dẫn xuất kế thừa các tính năng của lớp cơ sở (lớp hiện có).

Có nhiều mô hình kế thừa khác nhau trong lập trình C ++.

Kế thừa đa cấp C ++

Trong lập trình C ++, không chỉ bạn có thể dẫn xuất một lớp từ lớp cơ sở mà bạn còn có thể dẫn xuất một lớp từ lớp dẫn xuất. Hình thức kế thừa này được gọi là kế thừa đa cấp.

class A { 
... .. ... 
};
class B: public A {
... .. ...
};
class C: public B {
... ... ...
};

Ở đây, lớp B có nguồn gốc từ lớp cơ sở A và lớp C có nguồn gốc từ lớp có nguồn gốc B .

Ví dụ 1: Kế thừa đa cấp C ++

#include <iostream>
using namespace std;

class A {
    public:
      void display() {
          cout<<"Base class content.";
      }
};

class B : public A {};

class C : public B {};

int main() {
    C obj;
    obj.display();
    return 0;
}

Đầu ra

Base class content.

Trong chương trình này, lớp C có nguồn gốc từ lớp B (được dẫn xuất từ ​​lớp cơ sở A ).

Các obj đối tượng của lớp C được xác định trong main()chức năng.

Khi display()hàm được gọi, display()trong lớp A được thực thi. Đó là vì không có display()chức năng trong lớp C và lớp B .

Trình biên dịch ngoại hình đầu tiên cho display()chức năng trong lớp C . Vì hàm không tồn tại ở đó, nó sẽ tìm hàm trong lớp B (vì C có nguồn gốc từ B ).

Hàm cũng không tồn tại trong lớp B , vì vậy trình biên dịch sẽ tìm kiếm nó trong lớp A (vì B có nguồn gốc từ A ).

Nếu display()hàm tồn tại trong C , trình biên dịch sẽ ghi đè display()lớp A (vì ghi đè hàm thành viên ).

Kế thừa nhiều C ++

Trong lập trình C ++, một lớp có thể được dẫn xuất từ ​​nhiều hơn một lớp cha. Ví dụ, một lớp Bat có nguồn gốc từ các lớp cơ sở Mammal và WingedAnimal . Nó có ý nghĩa vì dơi là động vật có vú cũng như động vật có cánh.Nhiều người thừa kế

Ví dụ 2: Kế thừa nhiều trong lập trình C ++

#include <iostream>
using namespace std;

class Mammal {
  public:
    Mammal() {
      cout << "Mammals can give direct birth." << endl;
    }
};

class WingedAnimal {
  public:
    WingedAnimal() {
      cout << "Winged animal can flap." << endl;
    }
};

class Bat: public Mammal, public WingedAnimal {};

int main() {
    Bat b1;
    return 0;
}

Đầu ra

Mammals can give direct birth.
Winged animal can flap.

Sự mơ hồ trong nhiều tài sản thừa kế

Vấn đề rõ ràng nhất với đa kế thừa xảy ra trong quá trình ghi đè hàm.

Giả sử, hai lớp cơ sở có cùng một chức năng không bị ghi đè trong lớp dẫn xuất.

Nếu bạn cố gắng gọi hàm bằng cách sử dụng đối tượng của lớp dẫn xuất, trình biên dịch sẽ hiển thị lỗi. Đó là bởi vì trình biên dịch không biết hàm nào để gọi. Ví dụ,

class base1 {
  public:
      void someFunction( ) {....}  
};
class base2 {
    void someFunction( ) {....} 
};
class derived : public base1, public base2 {};

int main() {
    derived obj;
    obj.someFunction() // Error!  
}

Vấn đề này có thể được giải quyết bằng cách sử dụng hàm phân giải phạm vi để chỉ định hàm nào sẽ phân loại base1 hoặc base2

int main() {
    obj.base1::someFunction( );  // Function of base1 class is called
    obj.base2::someFunction();   // Function of base2 class is called.
}

Kế thừa phân cấp C ++

Nếu nhiều lớp được kế thừa từ lớp cơ sở, nó được gọi là kế thừa phân cấp . Trong kế thừa phân cấp, tất cả các tính năng phổ biến trong các lớp con đều được đưa vào lớp cơ sở.

Ví dụ, Vật lý, Hóa học, Sinh học có nguồn gốc từ lớp Khoa học. Tương tự như vậy, Dog, Cat, Horse có nguồn gốc từ lớp Động vật.

Cú pháp kế thừa phân cấp

class base_class {
     ... .. ...
}

class first_derived_class: public base_class {
     ... .. ...
}

class second_derived_class: public base_class {
     ... .. ...
}

class third_derived_class: public base_class {
     ... .. ...
}

Ví dụ 3: Kế thừa phân cấp trong lập trình C ++

// C++ program to demonstrate hierarchical inheritance

#include <iostream>
using namespace std;

// base class
class Animal {
   public:
    void info() {
        cout << "I am an animal." << endl;
    }
};

// derived class 1
class Dog : public Animal {
   public:
    void bark() {
        cout << "I am a Dog. Woof woof." << endl;
    }
};

// derived class 2
class Cat : public Animal {
   public:
    void meow() {
        cout << "I am a Cat. Meow." << endl;
    }
};

int main() {
    // Create object of Dog class
    Dog dog1;
    cout << "Dog Class:" << endl;
    dog1.info();  // Parent Class function
    dog1.bark();

    // Create object of Cat class
    Cat cat1;
    cout << "\nCat Class:" << endl;
    cat1.info();  // Parent Class function
    cat1.meow();

    return 0;
}

Đầu ra

Dog Class:
I am an animal.
I am a Dog. Woof woof.

Cat Class:
I am an animal.
I am a Cat. Meow.

Ở đây, cả Dogvà Catcác lớp đều có nguồn gốc từ Animallớp. Như vậy, cả hai lớp dẫn xuất đều có thể truy cập info()hàm thuộc về Animallớp đó.









Gõ tìm kiếm nhanh...