Saturday, October 7, 2017

Kuliah 5 C++: Pewarisan


BAB 5.
Pewarisan






5.1 Pengantar
Pewarisan merupakan sebuah fitur penting dari pemrograman berorientasi objek (PBO). Dimisalkan bahwa Anda telah menulis sebuah program kelas untuk menjelaskan sejumlah fitur dari sekelompok objek. Dan Anda juga mengetahui bahwa subgrup dari sekumpulan objek itu memiliki beberapa fitur spesial. Daripada membuat sebuah program kelas utuh mulai dari awal untuk menjelaskan fitur-fitur spesial berikut dengan fitur-fitur lain yang telah Anda jelaskan pada program kelas utama, Anda sebaiknya menuliskan sebuah program kelas baru yang mewarisi kelas yang sudah ada, yaitu mewarisi semua fungsi dan semua anggota datanya, dan menambahkan fitur-fitur spesial yang ingin Anda tambahkan pada subgrup objek tertentu. Jadi, Anda menggunakan kembali program kelas yang telah ada tanpa perlu memodifikasinya. Kelas yang baru disebut dengan kelas terderivasi dan kelas yang telah ada disebut dengan kelas basis. Prosesnya tidak berhenti di sini, Anda bisa saja memiliki kelas terderivasi lain yang mewarisi fitur-fitur dari kelas terderivasi atau fitur-fitur dari kelas terderivasi yang ditambah denan fitur-fitur dari beberapa kelas lain. Ketika sebuah kelas mewarisi satu kelas basis, maka mekanisme ini disebut dengan pewarisan tunggal. Ini diilustrasikan pada Gambar 5.1. Katakanlah kelas D adalah kelas terderivasi dan kelas B adalah kelas basis, pada kasus pewarisan tunggal, kelas terderivasi dideklarasikan sebagai berikut.

class D : penspesifikasi_akses B


GAMBAR 5.1 Pewarisan tunggal, contoh deklarasi (class D : public B)


Penspesifikasi akses dapat berupa public atau protected atau private. Sebagai contoh, untuk pewarisan publik, kode untuk pendeklarasian kelas D adalah:

class D : public B

C++ juga mendukung pewarisan lebih dari satu kelas dengan pelbagai cara seperti diilustrasikan pada Gambar 5.2 berikut. Kelas-kelas dari mana sebuah kelas diderivasi bisa berelasi atau boleh juga tidak berelasi satu sama lain.



GAMBAR 5.2 Hierarki pewarisan dengan lebih dari satu kelas basis

Gambar 5.2 menunjukkan cara kompleks dimana bangun-bangun poligonal berelasi satu sama lain. Bahkan rancangan produk industri seperti mobil dan lainnya dipengaruhi oleh persepsi-persepsi konsumen (Gambar 5.3). Ini menunjukkan bahwa produki industri memiliki interkoneksi dengan cara yang kompleksi.


GAMBAR 5.3 Hierarki pewarisan pada produk industri



5.2 Bentuk-Bentuk Pewarisan
Kelas-kelas basis dan kelas-kelas terderivasi dapat berelasi dengan sejumlah cara seperti diilustrasikan pada Gambar 5.4 (a-e). Kode-kode untuk pendeklarasian kelas terderivasi diberikan di bawah dari tiap gambar.








Seperti diilustrasikan pada gambar-gambar tersebut, pewarisan dapat dideklarasikan public, private atau protected. Namun, pada semua deklarasi atas kelas-kelas terderivasi, kata pertama adalah class (katakunci). Katakunci ini kemudian diikuti oleh nama kelas terderivasi, yang diikuti olah kolon (:) dan kemudian diikuti oleh penspesifikasi akses dan nama dari kelas basis. Pada kasus kelas basis lebih dari satu, penspesifikasi akses harus disebutkan secara individual dengan tiap kelas. Dimisalkan bahwa B adalah kelas basis dan D adalah kelas terderivasi. Deklarasi atas kelas D dengan kasus pewarisan tunggal dapat dituliskan berikut.

class D : public B         //pewarisan publik
class D : protected B      //pewarisan terproteksi
class D : private B        //pewarisan privat
class D : B                //tidak ada penspesifikasi akses, jadi
//secara default menjadi pewarisan privat

Gambar 5.4(a-e) juga menunjukkan kode-kode untuk pendeklarasian kelas terderivasi pada sejumlah tipe pewarisan yang berbeda.



5.3 Pewarisan Publik Tunggal
Pada jenis pewarisan ini, fungsi-fungsi publik pada kelas basis dapat diakses secara langsung oleh anggota-anggota kelas terderivasi, yaitu kelas-kelas terderivasi yang mewarisi fungsi-fungsi ini. Objek-objek dari kelas terderivasi dapat secara langsung mengakses fungsi-fungsi publik dari kelas basis. Anggota-anggota terproteksi pada kelas basis dapat diakses oleh kelas terderivasi melalui fungsi-fungsi publik dari kelas terderivasi sedangkan anggota-anggota private pada kelas basis tidak dapat diakses oleh kelas terderivasi. Anggota-anggota private pada kelas basis hanya dapat diakses melalui fungsi-fungsi publik dan fungsi-fungsi terproteksi pada kelas basis. Tetapi, fungsi friend dari kelas basis dapat mengakses semua anggota (publik, privat, terproteks) pada kelas basis. Fungsi-fungsi friend tidak diwariskan. Objek-objek dari kelas terderivasi adalah juga objek-objek dari kelas basis tetapi tidak berlaku sebaliknya.

Jika kelas basis hanya memiliki anggota-anggota publik dan kondisi pewarisan juga publik maka semua anggota pada kelas basis dapat diakses langsung oleh fungsi-fungsi anggota dan oleh objek-objek kali kelas terderivasi. Program 5.1 sampai program 5.3 mengilustrasikan pewarisan publik dengan kelas basis memiliki beberapa kategori anggota.
a.        Kelas basis hanya memiliki anggota-anggota publik (program 5.1).
b.       Kelas basis memiliki anggota-anggota publik dan terproteksi (program 5.2).
c.        Kelas basis memiliki anggota-anggota publik dan privat (program 5.3).

Program 5.1 Mengilustrasikan pewarisan publik dengan kelas basis hanya memiliki anggota-anggota publik

#include <iostream>
using namespace std;

class B
{
   public :
      int m ,a ;
      int Perkalian1() {return a*m;}
}; //akhir dari kelas B

class D : public B //deklarasi atas kelas terderivasi D
{
   public:
      int n ;
      int Perkalian2() {return n* Perkalian1();}
}; //akhir dari kelas D

int main()
{
   D C1;      // C1 adalah sebuah objek dari kelas D
  
   C1.m = 5;  //data secara langsung diakes oleh objek
   C1.a = 4 ;
   C1.n = 3 ;

   cout<<"Perkalian1 = "<<C1.Perkalian1()<<endl;
   cout<<"Perkalian2 = "<<C1.Perkalian2()<<endl;

   return 0;
}
KELUARAN
Perkalian1 = 20
Perkalian2 = 60



Pada program tersebut, objek C1 dari kelas terderivasi D memiliki akses langsung terhadap anggota-anggota publik dari kelas basis. Ini diilustrasikan oleh statemen C1.m = 5; dan statemen C1.Perkalian1();.

Jika kelas basis memiliki anggota-anggota publik dan terproteksi, maka semua anggota dari kelas basis itu dapat diakses oleh anggota-anggota dari kelas terderivasi. Anggota-anggota terproteksi dari kelas basis tidak dapat diakes secara langsung oleh objek-objek dari kelas terderivasi. Hal itu harus dilakukan melalui fungsi-fungsi publik dari kelas terderivasi.

Program 5.2 Mengilustrasikan pewarisan publik dengan kelas basis hanya memiliki anggota-anggota publik dan terproteksi

#include <iostream>
using namespace std;

class B //deklarasi atas kelas B
{
   protected :
      int m ; //anggota terproteksi dari kelas B

   public:
      int k;
      int Kuadrat() {return k*k ;}
      int Perkalian() {return k*m;}
}; //akhir dari kelas B

class D : public B //kelas D mewarisi kelas B
{
   public:
      void setNilai1(int a) //fungsi publik untuk mengakses m dari kelas B
      {m = a;}
}; //akhir dari kelas D.

int main()
{
   D C;                    //C dideklarasikan sebagai objek dari D
  
   C.k = 9;          //Akses langsung terhadap k dari kelas B
   C.setNilai1(6);   //Akses terhadap m melalui anggota publik dari D

   cout<<"Kuadrat = "<<C.Kuadrat()<<", Perkalian = "<< C.Perkalian()<<endl;

   return 0;
}
KELUARAN
Kuadrat = 81, Perkalian = 54



Pada program tersebut, anggota data terproteksi dari kelas B diakses melalui anggota fungsi publik dari kelas D, yaitu void setNilai1(int a){m = a ;}.

Anggota-anggota private dari kelas basis tidak dapat diakses langsung oleh fungsi-fungsi publik dari kelas terderivasi. Anggota private dari kelas basis ketika diakses oleh anggota dari kelas terderivasi akan menyebabkan error seperti diilustrasikan oleh keluaran program berikut.

Program 5.3 Mengilustrasikan pewarisan publik dengan kelas basis hanya memiliki anggota private

#include <iostream>
using namespace std;

class B
{
   private : //akses private
      int m ;
}; //akhir dari kelas B

class D : public B //deklarasi atas kelas D
{
   public:
      int a;
      void setNilai() //fungsi untuk mengakses m dari kelas B
      {m = a;}

      int n;
}; //akhir dari kelas D

int main()
{
   D C;              //C adalah sebuah objek dari kelas D

   C.a = 5;
   C.n = 4;

   int kali = C.a* C.n;

   cout<<"Perkalian atas angota-anggota = "<<kali<<endl;
   cout<<"Penjumlahan dari anggota-anggota terkuadrat = "<<C.n*C.n + C.a*C.a<<endl;

   return 0;
}
KELUARAN
cannot access private member declared in class 'B'



Jika diperlukan untuk mengakses anggota data private atau anggota fungsi private dari kelas basis, maka fungsi-fungsi publik yang menyediakan akses terhadap anggota-anggota private harus dicantumkan di dalam kelas basis. Fungsi-fungsi berperan seperti antarmuka. Anggota-anggota private dari kelas basis hanya dapat diakses melalui fungsi-fungsi publik dan terproteksi dari kelas basis atau oleh fungsi-fungsi friend dari kelas basis. Tetapi fungsi-fungsi friend tidak diwariskan.

Tetapi, anggota-anggota terproteksi dari kelas basis dapat diakses oleh fungsi-fungsi anggota publik dari kelas terderivasi. Ini telah diilustrasikan pada program 5.2. Perhatikan program berikut.

Program 5.4 Mengilustrasikan pewarisan publik dengan kelas basis hanya memiliki anggota data private dan anggota fungsi private

#include <iostream>
using namespace std;

class B { //kelas basis B
   private:
      int x;  //anggota private dari kelas B
      int Kuadrat(){return x*x ;}        //anggota private dari kelas B

   public:
      void setNilai(int p);              //setNilai()-sebuah anggota publik untuk
                                         //mengakses anggota private x dari kelas B
      int Pkuadrat(){return Kuadrat();}  //Sebuah anggota publik dari kelas B untuk
                                         //mengakes anggota private Kuadrat()
      int m;
}; //akhir dari kelas B

void B::setNilai(int p){x = p;}; //definisi dari setNilai()

class D : public B //deklarasi dari D dengan pewarisan publik
{
   public:
      int n ;
}; //akhir dari kelas D

int main()
{
   D C;                    //C adalah sebuah objek dari kelas D

   C.setNilai(5) ;   //mengakses x dari kelas B melalui setNilai()

   C.m = 4;          //mengakses anggota publik dari kelas B secara langsung
   C.n = 3;          //mengakses anggota publik dari kelas B secara langsung

   cout<<"Perkalian atas m dan n = "<<C.m*C.n<<endl;
   cout<<"Kuadrat = "<<C.Pkuadrat()<<endl;

   return 0;
}
KELUARAN
Perkalian atas m dan n = 12
Kuadrat = 25



Pada kelas B, terdapat sebuah anggota data private int x; dan sebuah anggota data publik int m; dan sebuah anggota fungsi private int square() {return x*x;}. Data private dari kelas B diakses dengan mendefinisikan sebuah fungsi publik void setNilai(int p); di dalam kelas B dan int Kuadrat() diakes dengan mendeklarasikan fungsi publik lain di dalam kelas B, yaitu int pKuadrat() {return Kuadrat();} dan fungsi publik ini diakses secara langsung oleh objek-objek dari kelas terderivasi D. Perhatikan pula bahwa Anda tidak bisa menuliskan berikut.

C.m*C.setNilai(5)

Ini karena fungsi setNilai() dideklarasikan void (tidak ada nilai balik). Jadi, penggunaan operator-operator aritmatika tidak legal pada fungsi void.



5.4 Pewarisan Terproteksi Tunggal
Pada kasus pewarisan terproteksi, anggota-anggota publik dan anggota-anggota terproteksi dari kelas basis menjadi anggota-anggota terproteksi dari kelas terderivasi. Anggota-anggota private dari kelas basis tidak dapat diakses oleh kelas terderivasi. Anggota-anggota itu hanya bisa diakses melalui fungsi-fungsi anggota terproteksi dan publik dari kelas basis. Program berikut mengilustrasikan pewarisan terproteksi dengan kelas basis memiliki anggota-anggota terproteksi dan publik.

Program 5.5 Mengilustrasikan pewarisan terproteksi ketika kelas basis memiliki anggota data dan anggota fungsi terproteksi dan publik

#include <iostream>
using namespace std;

class B {
   protected :       //akses terproteksi
      int m; 
      int Kuadrat() {return m*m;}

   public:           //akses publik
      int k;
      perkalian() {return k*m;}
}; //akhir dari kelas B

class D : protected B //pewarisan terproteksi
{
   public:
      void setNilai1(int a) //anggota publik untuk mengakses m
      {m = a;}
     
      void setNilai2(int p) {k = p;} //anggota publik untuk mengakses k
      int dKuadrat(){return B::Kuadrat();}             //untuk mengakses Kuadrat()
      int dperkalian(){return B::perkalian();}  //untuk mengakses perkalian()
}; //akhir dari kelas D

int main()
{
   D C;              //C adalah sebuah objek dari kelas D

   C.setNilai2(10);
   C.setNilai1(5);

   cout<<"Perkalian atas m dan k = "<<C.dperkalian()<<endl;
   cout<<"Kuadrat = "<<C.dKuadrat()<<endl;

   return 0;
}
KELUARAN
Perkalian atas m dan k = 50
Kuadrat = 25



Pada kasus pewarisan terproteksi, anggota-anggota publik dan terproteksi dari kelas basis menjadi anggota-anggota private dari kelas terderivasi. Anggota-anggota itu bisa diakses oleh fungsi-fungsi anggota publik dari kelas terderivasi.

Tetapi anggota-anggota private tidak dapat diakses oleh anggota-anggota dari kelas terderivasi secara langsung. Anggota-anggota itu hanya dapat diakses melalui fungsi-fungsi anggota publik dan terproteksi dari kelas basis itu sendiri. Pada program berikut, Anda memiliki sebuah kelas basis dengan anggota-anggota data private dan anggota fungsi private. Untuk mengakses kedua anggota itu, Anda perlu menciptakan fungsi-fungsi publik pada kelas basis itu sendiri. Untuk mengakses data private m, Anda memiliki fungsi apublik set_nilai() dan untuk fungsi private Kuadrat(), Anda menyedikan fungsi publik bKuadrat() yang menghasilkan nilai balik dari Kuadrat().

Program 5.6 Mengilustrasikan pewarisan terproteksi ketika kelas basis memiliki anggota-anggota private

#include <iostream>
using namespace std;

class B { //kelas basis
   private:
      int m;  //anggota data private
      int Kuadrat(){return m*m ;} //anggota fungsi private

   public :
      void set_nilaib(int a) {m = a;}    //anggota publik untuk mengakses m
      int bKuadrat(){return Kuadrat();} //untuk mengakses Kuadrat()

      int k; //anggota publik dari kelas B
      int perkalian(){return k*k;}
}; //akhir dari kelas B

class D : protected B //pewarisan terproteksi
{
   public:
      void set_nilaid (int n) {set_nilaib(n);}
      void set_nilai2(int p) {k = p;}           //untuk mengakses k,
      int dbkuadrat(){return bKuadrat();} //untuk mengakses bKuadrat()
      int dperkalian(){return perkalian();}     //untuk mengakses perkalian()
}; //akhir dari kelas D.

int main()
{
   D C; //C adalah sebuah objek dari kelas D

   C.set_nilai2(10);
   C.set_nilaid(5);

   cout<<"Perkalian = "<<C.dperkalian()<<endl;
   cout<<"Kuadrat = "<<C.dbkuadrat()<<endl;

   return 0;
}
KELUARAN
Perkalian = 100
Kuadrat = 25



5.5 Pewarisan Private Tunggal
Dengan pewarisan private, anggota-anggota publik dan terproteksi dari kelas basis menjadi anggota-anggota private dari kelas terderivasi. Jadi, anggota-anggota itu tidak dapat diakses secara langsung oleh sebuah objek dari kelas terderivasi. Namun, anggota-anggota itu dapat diakses melalui anggota-anggota fungsi publik dari kelas terderivasi. Anggota-anggota private dari kelas basis tidak dapat diakses oleh kelas terderivasi, karena mereka hanya bisa diakses melalui fungsi-fungsi anggota dan terproteksi dari kelas basis.

Program 5.7 Mengilustrasikan bahwa pada pewarisan private, anggota-anggota terproteksi dan publik dari kelas basis menjadi anggota-anggota private pada kelas terderivasi

#include <iostream>
using namespace std;

class B {
   protected :
      int m;

   public:
      int k;
}; //akhir dari kelas B

class D : private B //pewarisan private
{
   public: //pemodifikasi akses pada kelas D
      int a;
      void set_nilai() {m = a;}
      int n;
};//akhir dari kelas D

int main()
{
   D C; //C adalah sebuah objek dari kelas D

   C.k = 6;
   C.a = 5;
   C.n = 4;

   int perkalian = C.a * C.n;

   cout<<"Perkalian dari anggota-anggota dari B dan D = "<<perkalian<< endl;
   cout<<"Penjumlahan atas kuadrat dari anggota-anggota dari B dan D = "<< C.n*C.n + C.a*C.a<<endl;

   return 0;
}
KELUARAN
'k' : cannot access public member declared in class 'B'



Pada program berikut, kondisi pewarisan adalah private. Kelas basis memiliki satu anggota data terproteksi m, satu anggota data publik k, dan sebuah fungsi publik Kuadrat(). Bagi kelas terderivasi, semua anggota itu menjadi private. Oleh karena itu, fungsi-fungsi publik dikembangkan di dalam kelas terderivasi sehingga anggota-anggota itu dapat diakses oleh objek dari kelas terderivasi.

Program 5.8 Mengilustrasikan bahwa pada pewarisan private, anggota-anggota terproteksi dan publik dari kelas basis diakses melalui fungsi-fungsi publik dari kelas terderivasi

#include <iostream>
using namespace std;

class B{
   protected :
      int m;

   public :
      int k;
      int Kuadrat() {return k*k;}
      int mskuadrat() {return m*m;}
}; //akhir dari kelas B

class D : private B //pewarisan private
{
   public:
      int a;
      void set_nilai1() //anggota publik dari D untuk mengakses
         {m = a;}                 //anggota terproteksi dari B
     
      void set_nilai2(int b) {k = b;}
      //anggota publik dari D yang diperlukan untuk mengakses anggta publik
      //dari B.

      //Karena pewarisan private, hal yang sama berlaku berikut.
      int dmkuadrat(){return mskuadrat();}
      int Dkuadrat(){return B::Kuadrat();}
}; //akhir dari kelas D

int main()
{
   D C; // C adalah sebuah objek dari kelas D

   C.set_nilai2(6);
   C.a = 5;
   C.set_nilai1();

   cout<<"Kuadrat = "<< C.Dkuadrat()<<endl;
   cout<<"Kuadrat dari m = "<<C.dmkuadrat()<<endl;

   return 0;
}
KELUARAN
Kuadrat = 36
Kuadrat dari m = 25



Dari hasil-hasil yang diperoleh dari sejumlah program yang telah diberikan, kondisi akses pada ketiga jenis pewarisan disimpulkan pada Tabel 5.1. Di sini, D adalah nama dari kelas terderivasi dan B adalah nama dari kelas basis.

TABEL 5.1a Pewarisan publik (class D : public B)
Penspesifikasi akses kelas basis
Akses pada kelas terderivasi
public
Publik. Secara langsung dapat diakses oleh fungsi-fungsi anggota dan objek-objek dari kelas D dan fungsi-fungsi friendnya.

protected
Terproteksi. Dapat diakses oleh fungsi-fungsi anggota dari kelas terderivasi dan fungsi-fungsi friendnya.

private
Tidak dapat diakses secara langsung oleh anggota-angota pada kelas terderivasi. Anggota-anggota private dari kelas basis dapat diakses, hanya melalui fungsi-fungsi anggota publik dan terproteksi dari kelas basis, oleh fungsi-fungsi anggota dan fungsi-fungsi friend dari kelas terderivasi.


TABEL 5.1b Pewarisan terproteksi (class D : protected B)
Penspesifikasi akses kelas basis
Akses pada kelas terderivasi
public
Terproteksi. Hanya dapat diakses oleh fungsi-fungsi anggota dan fungsi-fungsi friend dari kelas terderivasi.

protected
Terproteksi. Hanya dapat diakses oleh fungsi-fungsi anggota dan fungsi-fungsi friend dari kelas terderivasi.

private
Tidak dapat diakes oleh kelas terderivasi. Hanya dapat diakses melalui anggota-anggota publik dan terproteksi dari kelas basis.


TABEL 5.1c Pewarisan private (class D : private B)
Penspesifikasi akses kelas basis
Akses pada kelas terderivasi
public
Private. Dapat diakses oleh fungsi-fungsi anggota dan fungsi-fungsi friend dari kelas terderivasi.

protected
Private. Dapat diakses oleh fungsi-fungsi anggota dan fungsi-fungsi friend dari kelas terderivasi.

private
Tidak dapat diakes oleh kelas terderivasi. Hanya dapat diakses melalui anggota-anggota publik dan terproteksi dari kelas basis.




5.6 Pewarisan Jamak
Gambar berikut mengilustrasikan pewarisan jamak dimana di dalamnya sebuah kelas diderivasi dari beberapa kelas basis.


GAMBAR 5.5 Pewarisan jamak---Kelas D diderivasi dari tiga kelas basis B1, B2, B3


Pada program berikut, kelas D diderivasi dari dua kelas basis D1 dan B2. Aturan-aturan pewarisan yang telah didiskusikan sebelumnya berlaku juga pada pewarisan jamak.

Program 5.9 Mengilustrasikan pewarisan jamak

#include <iostream>
using namespace std;

class B1 {
   private :
      int m ;

   public :
      int a;
      void set_nilai()
      {m = a;}
}; //akhir dari kelas B1

class B2
{
   public :
      int k;
}; //akhir dari kelas B2

class D : public B1, public B2
//deklarasi pewarisan jamak
{
   public:
      int n ;
};
//akhir dari kelas D

int main()
{
   D C;                    //C dideklarasikan sebagai objek dari kelas D

   C.k = 5;          //C mengakses langsung anggota publik dari B2
   C.a = 4;          //C mengakses langsung anggota publik dari B1
   C.n = 3;

   int perkalian = C.a* C.n*C.k;

   cout<<"Perkalian dari anggota-anggota data dari B1, B2, dan D = "<<perkalian<< endl;

   return 0;
}
KELUARAN
Perkalian dari anggota-anggota data dari B1, B2, dan D = 60



5.7 Pewarisan Multilevel
Pewarisan multilevel diilustrasikan pada Gambar 5.4c. Gambar tersebut menunjukkan bahwa kelas A merupakan kelas basis untuk kelas B dan kelas B menjadi kelas basis untuk kelas C. Aturan-aturan pewarisan seperti yang telah didiskusikan berlaku pada mekanisme pewarisan multilevel ini. Ini diilustrasikan pada program berikut dimana di dalamnya kelas B merupakan kelas basis bagi kelas terderivasi D1 yang merupakan kelas basis bagi kelas D2. Ketiga kelas tersebut memuat sebuah fungsi dengan nama sama Tampil(). Pada main(), fungsi-fungsi tersebut dipanggil. Untuk menghapus ambiguitas tentang fungsi Tampil() dari kelas mana yang dipanggil, operator resolusi skop dipakai untuk memanggil fungsi Tampil() dari kelas B dan kelas D1. Untuk fungsi Tampil() dari kelas D2, operator resolusi skop tidak diperlukan karena pemanggilan fungsi dari objek D2 akan mengacu ke fungsi dari kelas D2.

Program 5.10 Mengilustrasikan pewarisan multilevel

#include <iostream>
using namespace std;

class B
{
   public:
      void Tampil() {cout<<"Ini adalah fungsi Tampil() dari kelas B"<<endl;}
};

class D1 : public B
{
   public:
      void Tampil() {cout<<"Ini adalah fungsi Tampil() dari kelas D1"<<endl;}
};

class D2 : public D1
{
   public:
      void Tampil() {cout<<"Ini adalah fungsi Tampil() dari kelas D2"<<endl;}
};

int main ()
{
   D2 d2 ; //d2 adalah sebuah objek dari kelas D2

   d2.B::Tampil();
   d2.D1::Tampil();
   d2.Tampil();

   return 0;
}
KELUARAN
Ini adalah fungsi Tampil() dari kelas B
Ini adalah fungsi Tampil() dari kelas D1
Ini adalah fungsi Tampil() dari kelas D2


Contoh berikut merupakan contoh lain dari pewarisan multilevel. Pada kasus ini, menggantikan fungsi konstruktor, fungsi publik lain dipakai untuk menginisialisasi objek-objek dari kelas-kelas yang berbeda. Konstruktor dan destruktor pada pewarisan akan didiskusikan pada Bagian 5.8 pada bab ini.

Program 5.11 Mengilustrasikan pewarisan multilevel

#include <iostream>
using namespace std;

class B
{
   protected:
      int bx;

   public:
      void Bset(int m) { bx = m ;}
      void Tampil(){cout<<"Tampil() dari kelas B "<<endl;}
}; //akhir dari kelas B

class D1 : public B
{
   protected:
      int D1x;

   public:
      void D1set(int n){ D1x = n;}
      void Tampil(){cout<<"Tampil() dari kelas D1"<<endl;}
}; //akhir dari kelas D1

class D2 : public D1
{
   protected:
      int D2x;

   public:
      void D2set(int p) { D2x = p ;}
      void Tampil(){cout<<"Tampil() dari kelas D2"<<endl;}
}; //akhir dari kelas D2

class D3 : public D2
{
   private:
      int D3x;

   public :
      void D3set(int q) { D3x = q;}
      int Perkalian() { return D3x * D2::D2x * D1::D1x * B::bx;}
      void Tampil(){ cout<<"Tampil() dari kelas D3 "<<endl;}
}; //akhir dari kelas D3

int main ()
{
   D3 d3;

   d3.D3set (10);
   d3.D2::D2set(4);

   d3.D1::D1set(3);
   d3.B::Bset(2);
   cout<<"Perkalian = "<<d3.Perkalian()<<endl;

   d3.Tampil();
   d3.D2::Tampil();

   d3.D1::Tampil();
   d3.B::Tampil();

   return 0 ;
}
KELUARAN
Perkalian = 240
Tampil() dari kelas D3
Tampil() dari kelas D2
Tampil() dari kelas D1
Tampil() dari kelas B



5.8 Konstruktor dan Destruktor Pewarisan
Pada contoh-contoh ilustratif sebelumnya, Anda telah menggunakan fungsi-fungsi publik, bukan konstruktor-konstruktor, untuk menginisialisasi objek-objek kelas. Jika kelas basis tidak memiliki fungsi-fungsi konstruktor atau jika fungsi-fungsi konstruktornya tidak memiliki argumen apapun, maka kelas terderivasi tidak akan memiliki fungsi konstruktor. Namun, jika sembarang kelas basis memiliki fungsi konstruktor yang mengambil satu argumen, maka kelas terderivasi harus memiliki fungsi konstruktor karena itu adalah tanggung-jawab dari konstruktor dari kelas terderivasi untuk menginisialisasi kelas basis atau menyuplai argumen kepada konstruktor kelas basis. Oleh karena itu, konstruktor kelas terderivasi membawa data untuk inisialisasinya sendiri dan untuk konstruktor kelas basis.

Ilustrasi dari konstruktor kelas terderivasi diberikan berikut. Dimisalkan bahwa kelas B1 dan kelas B2 adalah masing-masing kelas basis dan dimisalkan bahwa kelas D adalah kelas terderivasi. Kelas B1 memiliki sebuah anggota data private int x dan B2 memiliki sebuah anggota data private int y. Konstruktor-konstruktor dari kelas-kelas basis adalah berikut.

B1(int n) {x = n;}         //konstruktor dari B1
B2(int m ) {y = m;}        //konstruktor dari B2

Konstruktor dari kelas terderivasi D, dimana di dalamnya int z merupakan sebuah anggota data private, diberikan berikut.

D (int i, int j, int k) : B1(i), B2(j) {z = k;}

Lihat secara hati-hati ekspresi tersebut. Konstruktor dideklarasikan untuk kelas D, jadi kata pertama adalah nama kelas, yaitu D. Nama kelas ini diikuti dengan nama-nama parameter yang diawali dengan tipe data masing-masing di dalam kurung. Kemudian terdapat sebuah kolon (:) yang diikuti oleh nama dari kelas basis pertama dengan parameter (i) di dalam kurung. Integer i adalah untuk konstruktor B1. Selanjutnya, ada koma dan kemudian nama dari kelas kedua B2 dan j di dalam kurung untuk konstruktor B2. Integer k adalah untuk konstruktor B2. Integer k dimaksudkan untuk kelas D dan ditugaskan kepada z di dalam kurung kurawal { dan }.

Pada konstruktor dari kelas D, int i dan int j adalah untuk konstruktor-konstruktor dari kelas-kelas basis dan int k adalah untuk anggota private dari kelas D. Urutan eksekusi dari konstruktor-konstruktor dan destruktor-destruktor dari kelas-kelas basis dan kelas-kelas terderivasi dicantumkan pada Tabel 5.2. Dapat diperhatikan bahwa konstruktor-konstruktor dari kelas-kelas basis dipanggil sesuai dengan urutan pendeklarasiannya pada deklarasi dari kelas terderivasi. Jadi, jika deklarasi diberikan berikut.

class D : public B1, public B2

maka konstruktor dari B1 akan dipanggil lebih dahulu yang diikuti dengan konstruktor dari B2 dan terakhir konstruktor dari D dipanggil. Untuk kasus destruktor, urutan ini dibalik. Pertama-tama, destruktor dari kelas D dipanggil kemudian destruktor dari kelas B2 dan kemudian destruktor dari B1. Program berikut mengilustrasikan diskusi ini.

Program 5.12 Mengilustrasikan definisi konstruktor pada kelas terderivasi

#include <iostream>
using namespace std;

class B1{
   private:
      int x;

   public:
      B1() {x =1;}         //konstruktor default dari B1
      B1(int a ) { x = a;} //konstruktor parametris dari B1
      int getx(){return x;} //fungsi publik dari B1
      ~B1() { }            //destruktor untuk B1
}; //akhir dari kelas B1

class B2 {
   int y;     //private secara default

   public:
      B2(){y=2;}
      B2(int b) {y = b;}   //konstruktor parametris dari B2
      ~B2(){}        //destruktor untuk B2
      int gety(){return y;}
}; //akhir dari kelas B2

class D : public B1, public B2
{
   private :
      int z;

   public :
      D(int i, int j, int k) : B1(i), B2(j) {z = k;}
      //Konstruktor untuk D

      ~D() {} //destruktor dari D
      int Perkalian() {return getx()* gety()*z;} //Sebuah fungsi publik dari D
}; //akhir dari kelas D

int main()
{
   D d (4, 5, 6); //d adalah sebuah objek dari kelas D

   cout<<"Perkalian = "<<d.Perkalian()<<endl;
   return 0;
}
KELUARAN
Perkalian = 120



Urutan dimana konstruktor-konstruktor dan destruktor-destruktor dieksekusi diilustrasikan pada program berikut.

Program 5.13 Mengilustrasikan urutan eksekusi dari konstruktor dan destruktor pada pewarisan

#include <iostream>
using namespace std;

class B1 { //awal dari kelas B1
   private:
      int x;

   public:
      B1() {x = 4;
            cout<<"Konstruktor dari B1 dipanggil\n";} 
      ~B1(){cout<<"Destruktor dari B1 dipanggil\n";}  
}; //akhir dari kelas B1

class B2 //awal dari kelas B2
{
   private:
      int y;

   public:
      B2() {y = 5;
            cout<<"Konstruktor dari B2 dipanggil\n";}
      ~B2(){cout<<"Destruktor dari B2 dipanggil\n";}
}; //akhir dari kelas B2

class D : public B1, B2    //kelas D diderivasi dari B1 dan B2
{
   private:
      int z;

   public:
      D (int c) { z =c; cout<<"Konstruktor dari D dipanggil\n";}
      ~D() {cout<<"Destruktor dari D dipanggil\n";}
}; //akhir dari kelas D

int main()
{
   D d (10);  //d dideklarasikan sebagai objek dari kelas D

   return 0;
}
KELUARAN
Konstruktor dari B1 dipanggil
Konstruktor dari B2 dipanggil
Konstruktor dari D dipanggil
Destruktor dari D dipanggil
Destruktor dari B2 dipanggil
Destruktor dari B1 dipanggil


Pada kasus dimana hanya terdapat satu kelas basis, konstruktor dari kelas basis itu dipanggil sebelum konstruktor dari kelas terderivasi. Jika terdapat beberapa kelas basis tetapi tidak ada kelas basis virtual, maka fungsi-fungsi konstruktor dari kelas basis dipanggil sesuai urutan dimana kelas-kelas basis dideklarasikan pada deklarasi dari kelas terderivasi.

Jika salah satu kelas basis adalah kelas basis virtual, maka konstruktornya menjadi yang pertama yang akan dipanggil yang diikuti oleh konstruktor-konstruktor dari kelas basis lain sesuai dengan urutan pendeklarasiannya. Sebagai contoh, dimisalkan bahwa kelas terderivasi dideklarasikan sebagai berikut.

class D : public B1, public B2 , public virtual B3

Konstruktor-konstruktor akan dipanggil dengan urutan berikut.

B3() Konstruktor dari kelas basis virtual B3
B1() Konstruktor dari kelas basis B1
B2() Konstruktor dari kelas basis B2
D() Konstruktor dari kelas terderivasi D

Tabel 5.2 juga memberikan urutan pemanggilan dari fungsi konstruktor dan destruktor untuk sejumlah kelas.

TABEL 5.2 Urutan eksekusi dari konstruktor dan destruktor pada pewarisan
Kategori pewarisan
Prioritas eksekusi dari konstruktor dan destruktor pada kelas basis dan kelas terderivasi
class D : public B
B() Konstruktor dari kelas basis B
D() Konstruktor dari kelas basis terderivasi D
~D() Destruktor dari kelas basis terderivasi D
~B() Destruktor dari kelas basis basis B
class D: public B1, public B2
B1() Konstruktor dari kelas basis B1
B2() Konstruktor dari kelas basis B2
D() Konstruktor dari kelas basis terderivasi D
~D() Destruktor dari kelas basis terderivasi D
~B2() Destruktor dari kelas basis basis B2
~B1() Destruktor dari kelas basis basis B1
class D: public B1, public virtual B2
B2() Konstruktor dari kelas basis virtual B2
B1() Konstruktor dari kelas basis B1
D() Konstruktor dari kelas basis terderivasi D
~D() Destruktor dari kelas basis terderivasi D
~B1() Destruktor dari kelas basis basis B1
~B2() Destruktor dari kelas basis basis B2


KONSTRUKTOR PENYALIN DAN PEWARISAN
Program berikut merupakan sebuah contoh dari konstruktor penyalin dan pewarisan.

Program 5.14 Mengilustrasikan konstruktor penyalin pada pewarisan

#include <iostream>
using namespace std;

class B
{
   protected:
      int x;

   public:
      B () { x = 4;}
      B(int a) {x = a;
                cout<<"Konstruktor basis dipanggil"<<endl;}

         B(const B &b) {x = b.x;
                        cout<<"Konstruktor penyalin dari kelas B dipanggil"<<endl;}
};

class D : public B
{
   int y; //private secara default

   public:
      D() {y = 5;}
      D(int k){y = k;
               cout<<"Konstruktor kelas terderivasi dipanggil"<<endl;}
     
      int Tampil() {return y;}
};

int main()
{
   D d1 (10); //d1 didefinisikan sebagai objek dari kelas D
   D d2 = d1; //d2 didefinisikan sebagai salinan dari d1.

   cout<<"d2 = "<<d2.Tampil()<<endl;

   return 0 ;
}
KELUARAN
Konstruktor kelas terderivasi dipanggil
Konstruktor penyalin dari kelas B dipanggil
d2 = 10


Program berikut merupakan contoh lain dari pendeklarasian konstruktor dari kelas terderivasi. Pada contoh ini, kelas Kubikel menghitung luas permukaan dari bangun prismatis yang memiliki tiga dimensi integer. Kelas ini merupakan kelas basis untuk kelas Kubik yang menggunakan luas permukaan untuk mencari biaya untuk melukis permukaan itu. Periksa konstruktor dengan nama Kubik pada program berikut.

Program 5.15 Mengilustrasikan konstruktor-konstruktor dari kelas basis dan kelas terderivasi

#include <iostream>
using namespace std;

class Kubikel {
   private:
      int x, y, z;

   public:
      Kubikel(){}
      Kubikel(int a, int b, int c ) //konstruktor
         {x = a;
          y = b;
          z = c;
          cout<<"konstruktor dari Kubikel dipanggil"<<endl;
         }

      int luas_permukaan() { return 2*(x*y +y*z +z*x);}
}; //akhir dari kelas Kubikel

class Kubik : public Kubikel
{
   public:
      int tarif;
      Kubikel C;

      //berikut adalah konstruktor dari kelas Kubik
      Kubik(int L, int W, int H, int A) : Kubikel (L, W, H) {tarif = A;}

      int biaya(int tarif, Kubikel C ){return tarif * C.luas_permukaan();}
}; //akhir dari kelas Kubik

int main()
{
   int x =2;

   Kubikel C1 (3, 3, 3);
   Kubikel C2 (4, 5, 6);

   Kubik Kubik1(3,3,3, x);
   Kubik Kubik2(4,5,6,3);

   cout<<"Luas permukaan dari Kubik1 = "<<Kubik1.luas_permukaan()<<"\n";
   cout<<"Biaya untuk Kubik1 = "<<Kubik1.biaya(x, C1 )<<"\n";

   cout<<"Luas permukaan dari Kubik2 = "<<Kubik2.luas_permukaan()<<"\n";
   cout<<"Biaya untuk Kubik2 = "<<Kubik2.biaya(3,C2)<<"\n";

   return 0;
}
KELUARAN
konstruktor dari Kubikel dipanggil
konstruktor dari Kubikel dipanggil
konstruktor dari Kubikel dipanggil
konstruktor dari Kubikel dipanggil
Luas permukaan dari Kubik1 = 54
Biaya untuk Kubik1 = 108
Luas permukaan dari Kubik2 = 148
Biaya untuk Kubik2 = 444



5.9 Pemuatan dan Pewarisan
Untuk banyak permasalahan riil, Anda akan memiliki kelas-kelas yang memuat objek-objek dari kelas-kelas lain sebagai anggota-anggotanya selain anggota-anggota fungsi dan data sendiri. Ini merupakan bentuk dari kelas pemuat. Bentuk lain dari kelas pemuat adalah bahwa sebuah kelas dideklarasikan di dalam kelas lain. Kelas pemuat akan memiliki karakteristik-karakteristik kelas-kelas yang dimuat melalui objek-objeknya. C++ juga mendukung relasi semacam itu. Ini juga merupakan metode alternatif selain pewarisan. Jadi, jika sebuah kelas D memuat objek-objek dari kelas B dan kelas C sebagai anggota-anggotanya, maka dapat dikatakan bahwa D memiliki relasi dengan C dan B. Di sini, akan didiskusikan bagaimana mendefinisikan konstruktor dari kelas pemuat. Dimisalkan terdapat tiga kelas B, C, dan D yang didefinisikan berikut. Kelas D memuat objek-objek dari kelas B dan kelas C.

class C
{
   int x; //private secara default

   public:
      C (int a) {x=a;} //konstruktor dari kelas C
      ———
}; //akhir dari kelas C

class B
{
   int y; // private by default

   public:
      B (int b) {y = b;} //konstruktor dari kelas B
      ———
}; //akhir dari kelas B

class D
{
   int z;

   public:
      C objek_C;
      B objek_B;

      //konstruktor dari kelas D diberikan berikut
      D(int i, int j, int k) : objek_C(i), objek_B(j){z = k;}
      ——
}; //akhir dari kelas D



Pada definisi tersebut, konstruktor untuk D memiliki tiga integer di dalam kurung yang diikuti oleh kolon (:). Konstruktor dari kelas B dan kelas C dipanggil dengan objek-objeknya, yaitu objek_B dan objek_C yang diikuti dengan tubuh konstruktor untuk kelas D, yaitu {z = k;}. Program berikut mengilustrasikannya.

Program 5.16 Mengilustrasikan konstruktor dari sebuah kelas yang memuat objek-objek dari kelas-kelas lain

#include <iostream>
using namespace std;

class C
{
   private:
      int x;

   public:
      C(int a) {x = a;
                cout<<"Konstruktor dari C dipanggil.\n";}
      ~C(){ cout<<"Destruktor dari C dipanggil.\n";}

      int getx() { return x;}
}; //akhir dari kelas C

class B {
   private:
      int y;

   public:
      B (int b) {y = b;
                 cout<<"Konstruktor dari B dipanggil.\n";}
      ~B(){cout<<"Destruktor dari B dipanggil.\n";}
      int gety(){return y;}
}; //akhir dari kelas B

class D
{
   private:
      int z;

   public:
      C objC ; //objC dideklarasikan sebagai objek dari kelas C
      B objB ; //objB dideklarasikan sebagai objek dari kelas B

      D (int i, int j, int k ) : objB (i), objC(j) {z =k ; cout<<"Konstruktor dari D dipanggil.\n";}

      ~D() {cout<<"Destruktor dari D dipanggil.\n";}

          int Perkalian(){return objC.getx()* objB.gety()* z;}
}; //akhir dari kelas D

int main()
{
   D objD(5, 20, 4);

   cout<<"Perkalian = "<<objD.Perkalian()<<endl;

   return 0;
}
KELUARAN
Konstruktor dari C dipanggil.
Konstruktor dari B dipanggil.
Konstruktor dari D dipanggil.
Perkalian = 400
Destruktor dari D dipanggil.
Destruktor dari B dipanggil.
Destruktor dari C dipanggil.



Sebuah kelas terderivasi dapat memuat objek-objek dari kelas lain, yang menyajikan kasus pewarisan dan pemuatan. Konstruktor kelas terderivasi menyuplai argumen-argumen bagi konstruktor-konstruktor kelas basis dan juga bagi kelas-kelas yang objek-objeknya dimuat di dalam kelas terderivasi tersebut. Untuk kelas yang dimuat, nama objeknya yang digunakan sedangkan untuk kelas basis, nama kelas yang dipakai untuk menyuplai argumen-argumen konstruktor. Program berikut mengilustrasikan hal ini.

Program 5.17 Mengilustrasikan konstruktor dari kelas terderivasi yang memiliki sebuah kelas basis dan yang memuat objek-objek dari kelas lain

#include <iostream>
using namespace std;

class C
{
   private:
      int x;

   public:
      C(int a) {x = a;
                cout<<"Konstruktor dari C dipanggil.\n";}
      ~C(){cout<<"Destruktor dari C dipanggil.\n";}

      int getx() { return x;}
}; //akhir dari kelas C

class B {
   private:
      int y;

   public:
      B (int b) {y = b;
                 cout<<"Konstruktor dari B dipanggil.\n";}
      ~B(){cout<<"Destruktor dari B dipanggil.\n";}
      int gety(){return y;}
}; //akhir dari kelas B

class D : public B   //kelas D diderivasi dari kelas B
{
   private:
      int z;

   public:
      C c ; //objek c dari kelas C di dalam kelas D

      // Below is the constructor of class D.
      D (int m, int n, int k ) : B(m), c(n)
      {
         z =k;
         cout<<"Konstruktor dari D dipanggil.\n";
      }
      //konstruktor dari B dipanggil dengan nama kelas B.
      //konstruktor dari C dipanggil dengan nama objeknya c.

      ~D() {cout<<"Destruktor dari D dipanggil.\n";}

      int Perkalian() {return c.getx()* gety()* z;}
}; //akhir dari kelas D

int main()
{
   D d(10, 20, 5); //objek dari kelas D

   cout<<"Perkalian = "<<d.Perkalian()<<endl;

   return 0;
}
KELUARAN
Konstruktor dari B dipanggil.
Konstruktor dari C dipanggil.
Konstruktor dari D dipanggil.
Perkalian = 1000
Destruktor dari D dipanggil.
Destruktor dari C dipanggil.
Destruktor dari B dipanggil.



Program 5.18 merupakan contoh lain dari pendeklarasian fungsi konstruktor pada pewarisan multilevel. Penulisan fungsi konstruktor sama dengan kelas yang memiliki kelas basis dan yang memuat objek-objek dari kelas-kelas lain.

Program 5.18 Mengilustrasikan konstruktor dari kelas terderivasi pada pewarisan multilevel

#include <iostream>
using namespace std;

class B {
   protected:
      int bx;

   public:
      B(){}
      B(int m) {bx = m;}

      int getbx(){return bx;}
}; //akhir dari kelas B

class D1
{
   protected:
      int D1x;

   public:
      D1(){}
      D1(int m) {D1x = m;}

      int getD1x(){return D1x;}
}; //akhir dari kelas D1

class D2 : public D1
{
   protected:
      int D2x;

   public:
      int getD2x(){return D2x;}
      D2(){}
      D2(int e) {D2x = e;}
}; //akhir dari kelas D2

class D3 : public D2
{
   private:
      int D3x;

   public:
      B b;    //b adalah sebuah objek dari kelas B
      D1 d1;  //d1 adalah sebuah objek dari kelas D1

      //konstruktor dari D didefinisikan berikut.
      D3 (int i, int j, int k, int s) : b(i), d1(j), D2(k) {D3x = s;}

      int Perkalian() {return D3x * D2x * d1.getD1x() * b.getbx();}
      void Tampil(){cout<<"Tampil() dari kelas D3."<<endl;}
}; //akhir dari kelas D3

int main ()
{
   D3 d3 ( 10, 5, 4, 2);

   cout<<"Perkalian = "<<d3.Perkalian()<<endl;

   return 0 ;
}
KELUARAN
Perkalian = 400



5.10 Fungsi Operator Terbebani dan Pewarisan
Fungsi terbebani dari kelas basis diwarisi oleh kelas terderivasi. Ini diilustrasikan oleh program berikut dimana di dalamnya fungsi operator += didefinisikan di dalam kelas basis. Fungsi ini dipanggil ketika ia diterapkan pada objek-objek dari kelas terderivasi.

Program 5.19 Mengilustrasikan pewarisan dari operator terbebani +=

#include<iostream>
using namespace std;

class Vektor
{
   protected:
      int x, y, z ; //tiga komponen vektor

   public:
      Vektor (){x=1, y=2, z=3;}
      Vektor (int a, int b,int c)
      {
         x =a ; y = b; z =c;
         cout<<"Konstruktor dari kelas Vektor dipanggil."<<endl;
      }

      Vektor operator += (const Vektor & P)
      {
         x = x + P.x ;
         y = y + P.y ;
         z = z + P.z ;
         cout<<"Fungsi terbebani dari Vektor dipanggil."<<endl;
         return *this;
      }

      void Tampil()
      {
         cout<<"Komponen x = "<<x<<endl;
         cout<<"Komponen y = "<<y<<endl;
         cout<<"Komponen z = "<<z<<endl;
      }
}; //akhir dari kelas Vektor

class D : public Vektor
{
   public:
      // constructor function
      D (int a, int b, int c) : Vektor (a,b,c)
      {
         cout<<"Konstruktor dari D dipanggil."<<endl;
      }
}; //akhir dari kelas D


int main()
{
   D V1(12, 4, 6), V2(3, 5, 7);

   V1 += V2;
   V1.Tampil();

   return 0;
}
KELUARAN
Konstruktor dari kelas Vektor dipanggil.
Konstruktor dari D dipanggil.
Konstruktor dari kelas Vektor dipanggil.
Konstruktor dari D dipanggil.
Fungsi terbebani dari Vektor dipanggil.
Komponen x = 15
Komponen y = 9
Komponen z = 13



LATIHAN
1.       Apa itu pewarisan? Bagaimana pewarisan berguna dalam pemrograman berorientasi objek?
2.       Apa jenis-jenis dari pewarisan?
3.       Apa perbedaan antara pewarisan tunggal dan pewarisan jamak? Jelaskan dengan diagram dan deklarasi kelas.
4.       Dengan bantuan diagram, tunjukkan pewarisan multi-lintasan. Juga, berikan contoh deklarasi kelas terderivasi.
5.       Pada kasus pewarisan tunggal, apakah perbedaan dari pewarisan publik dan pewarisan private?
6.       Pada kasus pewarisan tunggal, bagaimana pewarisan publik dan pewarisan terproteksi berbeda?
7.       Apa perbedaan antara pewarisan jamak dan pewarisan multilevel? Jelaskan dengan diagram dan pendeklarasian kelas.
8.       Bagaimana Anda mengakses anggota-anggota publik dan terproteksi dari kelas basis pada pewarisan publik?
9.       Bagaimana sebuah objek dari kelas terderivasi mengakses fungsi private dari kelas basis?
10.    Sebuah kelas terderivasi D diderivasi dari dua kelas basis B1 dan B2 yang masing-masing memiliki satu anggota data private dan fungsi konstruktor. Kelas terderivasi D juga memiliki sebuah anggota data private. Bagaimana Anda mendefinisikan fungsi konstruktor untuk kelas D?
11.    Apakah urutan eksekusi dari konstruktor-konstruktor pada deklarasi kelas berikut?
a.        class D : public class B1, public class B2
b.       class D : public virtual class V, private class B1, public class B2
c.        class D : public B1, public B2, public virtual V.
12.    Berikan satu contoh konstruktor dari kelas terderivasi pada pewarisan publik tunggal dimana di dalamnya kelas basis memiliki satu anggota data private integer dan kelas terderivasi memiliki satu anggota data private bertipe double.
13.    Pada pewarisan multileval, konstruksilah sebuah fungsi konstruktor dari kelas D2 yang diderivasi dari kelas D1 yang diderivasi dari kelas D yang diderivasi dari kelas B. Semua kelas kecuali kelas D2 memiliki satu anggota data terproteksi sedangkan kelas D2 memiliki satu anggota data private.
14.    Tulislah sebuah program untuk mendeklarasikan sebuah kelas terderivasi dengan nama Nilai dari kelas basis Mahasiswa. Kelas basis tersebut memiliki nomor-nomor mahasiswa dan nama-nama sedangkan kelas Nilai memiliki nomor-nomor mahasiswa dan nilai-nilai. Kelas terderivasi tersebut menampilkan tiap nama mahasiswa, tiap nomor mahasiswa, dan tiap nilai yang diterimanya.
15.    Apa itu pemuatan? Bagaimana Anda mendefinisikan fungsi konstruktor dari sebuah kelas yang memuat objek-objek dari dua kelas lain?
16.    Sebuah kelas D diderivasi dari kelas B dan memuat objek dari kelas C. Jika semua kelas memiliki konstruktor, bagaimana Anda mendefinisikan fungsi konstruktor dari kelas D?
17.    Apakah Anda memerlukan fungsi konstruktor jika kelas basis dan kelas terderivasi hanya memiliki fungsi publik?
18.    Apa urutan pemanggilan dari fungsi-fungsi destruktor pada suatu pewarisan multilevel?