Untuk menjawab pertanyaan itu, saya ingin menggambarkan aksesor anggota pertama dengan kata-kata saya sendiri. Jika Anda sudah tahu ini, lewati ke judul "selanjutnya:".
Ada tiga accesor bahwa aku menyadari: public
, protected
dan private
.
Membiarkan:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
- Segala sesuatu yang disadari
Base
juga sadar yang Base
berisi publicMember
.
- Hanya anak-anak (dan anak-anak mereka) yang sadar yang
Base
berisi protectedMember
.
- Tidak ada
Base
yang menyadari privateMember
.
Dengan "menyadari", maksud saya "mengakui keberadaan, dan dengan demikian dapat mengakses".
lanjut:
Hal yang sama terjadi dengan warisan publik, swasta dan dilindungi. Mari kita pertimbangkan kelas Base
dan kelas Child
yang mewarisi dari Base
.
- Jika warisan itu
public
, segala sesuatu yang sadar Base
dan Child
juga sadar yang Child
mewarisi dari Base
.
- Jika warisan itu
protected
, hanya Child
, dan anak-anaknya, sadar bahwa mereka mewarisinya Base
.
- Jika warisan itu
private
, tidak ada orang lain Child
yang menyadari warisan itu.
SomeBase
sama seperti cara hardcode untuk menulis-dalam anggota tipe anonimSomeBase
. Ini, seperti anggota lainnya, memiliki penentu akses, yang memberikan kontrol yang sama pada akses eksternal.CATATAN PENTING: Kelas B, C dan D semuanya berisi variabel x, y dan z. Ini hanya masalah akses.
Tentang penggunaan warisan yang dilindungi dan pribadi, Anda dapat membaca di sini .
sumber
Membatasi visibilitas pewarisan akan membuat kode tidak dapat melihat bahwa beberapa kelas mewarisi kelas lain: Konversi tersirat dari turunan ke pangkalan tidak akan berfungsi, dan
static_cast
dari pangkalan ke turunan tidak akan berfungsi baik.Hanya anggota / teman dari suatu kelas yang dapat melihat warisan pribadi, dan hanya anggota / teman dan kelas turunan yang dapat melihat warisan yang dilindungi.
warisan publik
Warisan IS-A. Sebuah tombol adalah-jendela, dan di mana pun di mana dibutuhkan sebuah jendela, sebuah tombol dapat dilewati juga.
warisan yang dilindungi
Dilindungi diimplementasikan dalam istilah-of. Sangat berguna. Digunakan
boost::compressed_pair
untuk mendapatkan dari kelas kosong dan menghemat memori menggunakan optimasi kelas dasar kosong (contoh di bawah ini tidak menggunakan template untuk tetap pada titik):warisan pribadi
Diimplementasikan-dalam-hal-dari. Penggunaan kelas dasar hanya untuk mengimplementasikan kelas turunan. Berguna dengan sifat dan jika ukuran penting (sifat kosong yang hanya berisi fungsi akan menggunakan optimasi kelas dasar kosong). Seringkali penahanan adalah solusi yang lebih baik. Ukuran untuk string sangat penting, jadi ini adalah penggunaan yang sering terlihat di sini
anggota publik
Agregat
Pengakses
anggota yang dilindungi
Memberikan peningkatan akses untuk kelas turunan
anggota pribadi
Simpan detail implementasi
Perhatikan bahwa cast gaya-C dengan sengaja memungkinkan casting kelas turunan ke kelas basis yang dilindungi atau privat dengan cara yang ditentukan dan aman dan untuk dilemparkan ke arah lain juga. Ini harus dihindari dengan cara apa pun, karena dapat membuat kode tergantung pada detail implementasi - tetapi jika perlu, Anda dapat menggunakan teknik ini.
sumber
Ketiga kata kunci ini juga digunakan dalam konteks yang sama sekali berbeda untuk menentukan model pewarisan visibilitas .
Tabel ini mengumpulkan semua kombinasi yang mungkin dari deklarasi komponen dan model pewarisan yang menyajikan akses yang dihasilkan ke komponen ketika subkelas sepenuhnya ditentukan.
Tabel di atas diinterpretasikan dengan cara berikut (lihat baris pertama):
Sebuah contoh:
Akses yang dihasilkan untuk variabel
p
,q
,r
di kelas Subsub adalah tidak ada .Akses yang dihasilkan untuk variabel
y
,z
di kelas Sub ini dilindungi dan untuk variabelx
adalah tidak ada .Sekarang mari kita mendefinisikan subclass:
Kelas yang didefinisikan bernama Sub yang merupakan subclass dari kelas bernama
Super
atauSub
kelas yang berasal dariSuper
kelas. TheSub
memperkenalkan kelas tidak variabel baru atau fungsi baru. Apakah ini berarti bahwa objek apa pun dariSub
kelas mewarisi semua sifat setelahSuper
kelas sebenarnya merupakan salinan dari objekSuper
kelas?Tidak ada . Tidak.
Jika kita mengkompilasi kode berikut, kita tidak akan mendapatkan apa-apa selain kesalahan kompilasi yang mengatakan bahwa
put
danget
metode tidak dapat diakses. Mengapa?Ketika kita menghilangkan specifier visibilitas, kompilator mengasumsikan bahwa kita akan menerapkan apa yang disebut warisan pribadi . Ini berarti bahwa semua masyarakat komponen superclass berubah menjadi pribadi akses, komponen superclass swasta tidak akan dapat diakses sama sekali. Karena itu berarti Anda tidak diperbolehkan menggunakan yang terakhir di dalam subkelas.
Kami harus memberi tahu kompiler bahwa kami ingin mempertahankan kebijakan akses yang sebelumnya digunakan.
Objek
Sub
kelas dapat melakukan "hampir" hal yang sama seperti saudara kandung mereka yang dibuat dariSuper
kelas. "Hampir" karena fakta menjadi subclass juga berarti bahwa kelas kehilangan akses ke komponen pribadi dari superclass . Kami tidak dapat menulis fungsi anggotaSub
kelas yang akan dapat secara langsung memanipulasi variabel penyimpanan.Ini adalah batasan yang sangat serius. Apakah ada solusi?
Ya .
Tingkat akses ketiga disebut dilindungi . Kata kunci yang dilindungi berarti bahwa komponen yang ditandai dengan itu berperilaku seperti yang umum ketika digunakan oleh salah satu subclass dan terlihat seperti yang pribadi ke seluruh dunia . - Ini hanya berlaku untuk kelas yang diwariskan kepada publik (seperti kelas Super dalam contoh kita) -
Seperti yang Anda lihat dalam kode contoh, kita memiliki fungsionalitas baru untuk
Sub
kelas dan melakukan satu hal penting: mengakses variabel penyimpanan dari kelas Super .Itu tidak akan mungkin jika variabel dinyatakan sebagai pribadi. Dalam lingkup fungsi utama, variabel tetap tersembunyi, jadi jika Anda menulis sesuatu seperti:
Kompiler akan memberi tahu Anda bahwa itu adalah
error: 'int Super::storage' is protected
.Akhirnya, program terakhir akan menghasilkan output berikut:
sumber
Ini berkaitan dengan bagaimana anggota publik dari kelas dasar diekspos dari kelas turunan.
Seperti ditunjukkan litb, warisan publik adalah warisan tradisional yang akan Anda lihat di sebagian besar bahasa pemrograman. Itu adalah model hubungan "IS-A". Warisan pribadi, sesuatu yang AFAIK khas C ++, adalah hubungan "IMPLEMENTED IN SYARAT OF". Itu adalah Anda ingin menggunakan antarmuka publik di kelas turunan, tetapi tidak ingin pengguna kelas turunan memiliki akses ke antarmuka itu. Banyak yang berpendapat bahwa dalam hal ini Anda harus mengagregasi kelas dasar, yang alih-alih menjadikan kelas dasar sebagai basis pribadi, buatlah anggota turunan untuk menggunakan kembali fungsionalitas kelas dasar.
sumber
Jenis warisan : Objek yang diwarisi sebagai :
sumber
1) Waris Publik :
Sebuah. Anggota pribadi kelas Base tidak dapat diakses di kelas Turunan.
b. Anggota kelas Base yang dilindungi tetap dilindungi di kelas Turunan.
c. Anggota umum dari kelas Base tetap umum di kelas turunan.
Jadi, kelas lain dapat menggunakan anggota publik dari kelas Base melalui objek kelas turunan.
2) Warisan yang Dilindungi :
Sebuah. Anggota pribadi kelas Base tidak dapat diakses di kelas Turunan.
b. Anggota kelas Base yang dilindungi tetap dilindungi di kelas Turunan.
c. Anggota publik dari kelas Base juga menjadi anggota yang dilindungi dari kelas turunan.
Jadi, kelas lain tidak bisa menggunakan anggota publik kelas Base melalui objek kelas turunan; tetapi mereka tersedia untuk subclass dari Turunkan.
3) Warisan Pribadi :
Sebuah. Anggota pribadi kelas Base tidak dapat diakses di kelas Turunan.
b. Anggota kelas Base yang dilindungi & publik menjadi anggota pribadi kelas Turunan.
Jadi, tidak ada anggota kelas Base yang dapat diakses oleh kelas lain melalui objek kelas Derived karena mereka pribadi di kelas Derived. Jadi, bahkan subkelas dari kelas turunan tidak dapat mengaksesnya.
sumber
Warisan publik memodelkan hubungan IS-A. Dengan
setiap
D
aB
.Warisan pribadi memodelkan hubungan IS-IMPLEMENTED-USING (atau apa pun namanya). Dengan
a
D
adalah tidak satuB
, tapi setiapD
menggunakan yangB
dalam pelaksanaannya. Warisan pribadi selalu dapat dihilangkan dengan menggunakan penahanan:Ini
D
juga dapat diimplementasikan menggunakanB
, dalam hal ini menggunakan nyab_
. Kontainmen adalah kopling yang kurang ketat antara tipe dibandingkan pewarisan, jadi secara umum seharusnya lebih disukai. Terkadang menggunakan penahanan alih-alih warisan pribadi tidak senyaman warisan pribadi. Seringkali itu alasan lemah untuk menjadi malas.Saya tidak berpikir ada yang tahu
protected
model pewarisan apa . Setidaknya saya belum melihat penjelasan yang meyakinkan.sumber
D
berasal dari pribadiD
, itu dapat mengesampingkan fungsi virtualB
. (Jika, misalnya,B
adalah antarmuka pengamat, makaD
dapat mengimplementasikannya dan beralihthis
ke fungsi yang memerlukan antarmuka, tanpa semua orang dapat menggunakanD
sebagai pengamat.) Juga,D
secara selektif dapat membuat anggota yangB
tersedia di antarmuka dengan melakukanusing B::member
. Keduanya secara sintaksis tidak nyaman untuk diterapkan ketikaB
menjadi anggota.protected
warisan yang saya temukan berguna denganvirtual
kelas dasar danprotected
ctor:struct CommonStuff { CommonStuff(Stuff*) {/* assert !=0 */ } }; struct HandlerMixin1 : protected virtual CommonStuff { protected: HandlerMixin1() : CommonStuff(nullptr) {} /*...*/ }; struct Handler : HandlerMixin1, ... { Handler(Stuff& stuff) : CommonStuff(&stuff) {} };
Jika Anda mewarisi secara publik dari kelas lain, semua orang tahu Anda mewarisi dan Anda dapat digunakan secara polimorfik oleh siapa saja melalui pointer kelas dasar.
Jika Anda mewarisi secara dilindungi hanya kelas anak-anak Anda yang akan dapat menggunakan Anda secara polimorfik.
Jika Anda mewarisi secara pribadi hanya diri Anda yang dapat menjalankan metode kelas induk.
Yang pada dasarnya melambangkan pengetahuan yang dimiliki seluruh kelas tentang hubungan Anda dengan kelas orang tua Anda
sumber
Anggota data yang dilindungi dapat diakses oleh setiap kelas yang mewarisi dari kelas Anda. Namun, anggota data pribadi tidak bisa. Katakanlah kita memiliki yang berikut ini:
Dari dalam ekstensi Anda ke kelas ini, referensi
this.myPrivateMember
tidak akan berfungsi. Namun,this.myProtectedMember
akan. Nilainya masih dienkapsulasi, jadi jika kita memiliki instance kelas ini dipanggilmyObj
, makamyObj.myProtectedMember
tidak akan berfungsi, jadi fungsinya mirip dengan anggota data pribadi.sumber
Berdasarkan contoh ini untuk java ... Saya pikir sebuah meja kecil bernilai seribu kata :)
sumber
Ringkasan:
Saat mewarisi, Anda dapat (dalam beberapa bahasa) mengubah jenis perlindungan anggota data ke arah tertentu, misalnya dari terlindung ke publik.
sumber
Pribadi:
Anggota pribadi dari kelas dasar hanya dapat diakses oleh anggota kelas dasar itu.
Publik:
Anggota publik dari kelas dasar dapat diakses oleh anggota kelas dasar itu, anggota kelas turunannya serta anggota yang berada di luar kelas dasar dan kelas turunan.
Terlindung:
Anggota yang dilindungi dari kelas dasar dapat diakses oleh anggota kelas dasar serta anggota kelas turunannya.
Pendeknya:
pribadi : basis
dilindungi : basis + berasal
publik : basis + berasal + anggota lain
sumber
Saya menemukan jawaban yang mudah dan berpikir untuk mempostingnya untuk referensi saya di masa depan juga.
Ini dari tautan http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
sumber
Ini pada dasarnya adalah perlindungan akses dari publik dan anggota kelas dasar yang dilindungi di kelas turunan. Dengan warisan publik, kelas turunan dapat melihat anggota pangkalan publik dan yang dilindungi. Dengan warisan pribadi, itu tidak bisa. Dengan dilindungi, kelas turunan dan kelas apa pun yang berasal dapat melihatnya.
sumber