Back to IF2010 Pemrograman Berorientasi Objek

Inheritance dan Polymorphism

Questions/Cues

  • Mengapa perlu Inheritance?
  • Bagaimana sintaks & mode pewarisan?
  • Apa itu Polymorphism & Dynamic Binding?
  • Apa peran keyword virtual?
  • Apa itu Virtual Destructor & mengapa penting?
  • Apa itu Abstract Base Class (ABC)?
  • Apa itu Diamond Problem?

Reference Points

  • Materi PDF: “Konsep Inheritance”, “Bahasa C++: Inheritance”, “Bahasa C++: Keyword ‘virtual’”
  • Materi Pendukung: “Tutorial 2”

Konsep Dasar Inheritance (Pewarisan)

Inheritance adalah kemampuan sebuah kelas (derived class atau subclass) untuk menurunkan (mewarisi) atribut dan method dari kelas lain (base class atau superclass). Ini merepresentasikan hubungan “is-a” (adalah seorang/sebuah), contohnya Mobil is-a Kendaraan.

Tujuannya adalah untuk code reuse dan menghindari logika kondisional yang kompleks. Daripada memiliki satu kelas Kendaraan dengan banyak if-else untuk kategori yang berbeda, lebih baik membuat subclass untuk setiap kategori (Bus, Minibus, dll.) yang mengimplementasikan perilakunya sendiri.

Sintaks & Mode Pewarisan

class Minibus: public Kendaraan { 
    // ... anggota kelas Minibus ...
};

Mode pewarisan (public, protected, private) menentukan bagaimana tingkat akses anggota dari base class akan terlihat di derived class. Pewarisan public adalah yang paling umum digunakan.

Polymorphism dan Dynamic Binding

Polymorphism (poly=banyak, morph=bentuk) adalah kemampuan sebuah pointer atau reference bertipe base class untuk menunjuk atau mengacu pada objek dari derived class-nya saat runtime.

Ini memungkinkan Dynamic Binding: proses penentuan versi method mana yang akan dipanggil terjadi pada saat runtime, berdasarkan tipe aktual dari objek yang ditunjuk, bukan tipe statik dari pointernya.

Peran Keyword virtual

Dynamic binding hanya terjadi jika method di base class dideklarasikan dengan keyword virtual. Tanpa virtual, pemanggilan method akan menggunakan static binding, di mana versi base class yang akan selalu dipanggil, mengabaikan tipe objek sebenarnya.

// Di Base class
virtual void f() { std::cout << "base\n"; }
 
// Di Derived class
void f() override { std::cout << "derived\n"; } // 'override' disarankan
 
// ... Di main()
Base* dp = new Derived();
dp->f(); // Akan mencetak "derived" karena f() adalah virtual

Fitur Penting dalam Inheritance

  • Virtual Destructor

    • Masalah: Jika Anda menghapus objek derived class melalui pointer base class (delete base_ptr;), hanya destructor dari base class yang akan dipanggil jika ia tidak virtual. Ini menyebabkan memory leak jika derived class mengelola sumber dayanya sendiri.
    • Solusi: Selalu jadikan destructor di base class virtual jika kelas tersebut dimaksudkan untuk digunakan secara polimorfik.
    class Base {
    public:
        virtual ~Base() { /* ... */ } // Virtual destructor
    };
  • Abstract Base Class (ABC)

    • Adalah kelas yang tidak bisa diinstansiasi (tidak bisa dibuat objeknya) dan berfungsi sebagai interface untuk kelas turunannya.
    • Sebuah kelas menjadi abstrak jika memiliki setidaknya satu pure virtual function, yaitu method yang dideklarasikan dengan = 0;.
    class Shape {
    public:
        virtual void Draw() = 0; // Pure virtual function
    };

    Derived class yang non-abstrak wajib mengimplementasikan semua pure virtual function dari ABC-nya.

Masalah dalam Multiple Inheritance

  • Diamond Problem: Terjadi ketika sebuah kelas D mewarisi dari dua kelas B dan C, yang keduanya sama-sama mewarisi dari kelas A. Ini menyebabkan D memiliki dua salinan anggota dari A, sehingga terjadi ambiguitas saat mengakses anggota tersebut.
  • Solusi C++: Menggunakan virtual inheritance. Kelas B dan C harus mewarisi dari A dengan keyword virtual (class B : virtual public A). Ini memastikan kelas D hanya akan memiliki satu salinan anggota dari A.

Summary

  • Inheritance memungkinkan pembuatan hierarki kelas dengan hubungan “is-a” untuk code reuse dan desain yang bersih. Keyword virtual adalah kunci untuk mengaktifkan polymorphism, di mana pointer base class dapat memanggil method dari derived class saat runtime (dynamic binding).
  • Untuk manajemen memori yang aman dalam polimorfisme, destructor pada base class harus virtual. Abstract Base Class (ABC) dengan pure virtual function digunakan untuk mendefinisikan interface yang tidak dapat diinstansiasi.