Mengapa kita tidak bisa mendefinisikan kelas sebagai protected
?
Aku tahu kita tidak bisa, tapi kenapa? Harus ada alasan khusus.
Mengapa kita tidak bisa mendefinisikan kelas sebagai protected
?
Aku tahu kita tidak bisa, tapi kenapa? Harus ada alasan khusus.
Jawaban:
Karena itu tidak masuk akal.
Anggota kelas yang dilindungi (metode atau variabel) sama seperti paket-privat (visibilitas default), kecuali bahwa ia juga dapat diakses dari subkelas.
Karena tidak ada konsep seperti 'subpackage' atau 'package-inheritance' di Java, mendeklarasikan class protected atau package-private akan menjadi hal yang sama.
Anda bisa mendeklarasikan kelas bersarang dan kelas dalam sebagai dilindungi atau privat.
open
di Kotlin yang mengizinkan subclassing di luar paket saat ini (bisa dibayangkan protected
di Java mencegahnya, dengan default yang berlawanan).
Seperti yang Anda ketahui default adalah untuk akses tingkat paket dan yang dilindungi adalah untuk tingkat paket ditambah kelas non-paket tetapi yang memperluas kelas ini (Poin yang perlu dicatat di sini adalah Anda dapat memperluas kelas hanya jika terlihat!). Mari kita begini:
Karena tidak ada cara untuk membatasi kelas ini menjadi subkelas hanya dengan beberapa kelas (kami tidak dapat membatasi kelas yang diwarisi hanya oleh beberapa kelas dari semua kelas yang tersedia dalam sebuah paket / di luar paket), tidak ada penggunaan penentu akses yang dilindungi untuk kelas tingkat atas. Oleh karena itu tidak diperbolehkan.
public class A
{
protected class B
{
}
}
@Nikita Rybak jawaban memiliki poin yang bagus tetapi kurang detail, saya tidak bisa begitu saja mendapatkan ide tanpa berpikir mendalam sendiri, berikut ini adalah apa yang saya pikirkan dan sekarang saya harus benar-benar memahami alasannya.
Empat pengubah akses, asumsikan level 1 adalah publik dan level 4 adalah privat (berdasarkan tabel ini secara berurutan). Hal pertama yang harus kita ketahui adalah mengapa kelas tidak dapat didefinisikan sebagai privat di tingkat atas.
Jadi jika "private class foo" (anggota pribadi didefinisikan, yaitu kelas itu sendiri adalah anggota) memungkinkan, apa yang di luar (yang berisi anggota)? Cakupan file? Tidak, file luar tidak ada gunanya karena bahkan beberapa kelas dalam satu file akan dikompilasi menjadi file kelas yang terpisah. Jadi bagian luarnya adalah paket . Tetapi pengubah akses default tingkat ke-3 sudah berarti "paket-pribadi ". Jadi pengubah akses pribadi tingkat 4 tidak akan digunakan / diizinkan.
Tetapi kelas privat bersarang diperbolehkan karena bagian luar langsungnya adalah kelas, bukan paket, misalnya :
class PrivateNestedMain {
private static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Sekarang bagaimana jika "kelas yang dilindungi foo" memungkinkan? Karakteristik utama yang dilindungi adalah subclass, jadi outer (package) HARUS (karena cakupan up-to, tapi tetap opsional) menyediakan gaya subclass , yaitu sub-paket, atau package A extends package B
, tetapi kita tidak tahu hal semacam itu. Jadi protected tidak bisa menggunakan potensi penuh (lingkup utama adalah subkelas-lebar) di tingkat atas yang luarnya adalah paket (yaitu tidak ada hal sub-paket seperti itu), tetapi dilindungi dapat menggunakan potensi penuh di kelas bersarang yang kelas luarnya ( yaitu dapat menjadi subkelas) :
class ProtectedNestedMain {
protected static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Perhatikan bahwa hal di atas mengatakan "tidak dapat menggunakan potensi penuh" karena tidak dapat menjangkau seluruh subkelas hanya karena tidak ada subkelas luar, itu berarti benar-benar dilindungi dapat diizinkan , itu hanya masalah pilihan untuk menghindari duplikasi tugas paket -private if outer not subclass-mampu , lihat di bawah.
Kebingungan saya terutama disebabkan oleh tabel terkenal di https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html :
Jika level 1 (publik) dan level 3 (paket-privat) diizinkan, bagaimana mungkin level antara 2 (dilindungi) tidak diizinkan?
subclass dukungan publik sehingga mudah menyesatkan. Cara yang benar untuk membaca tabel ini adalah
public support subclass jika bagian luarnya memiliki fitur subclass.
Hal menyesatkan yang sama berlaku untuk package-private, package-private tidak mendukung subclass ( N dalam sel) tidak berarti konsep subclass berlaku di luar.
Itu berarti kita harus mengabaikan kolom Subclass jika fitur subclass tidak tersedia di luar:
Seperti yang bisa kita lihat sekarang, baik protected maupun package-private berada pada level yang sama sekarang ( YYN ), tidak ada lagi kebingungan tentang mengapa level di antara tidak diizinkan. Secara keseluruhan, Java hanya memilih paket-pribadi daripada dilindungi untuk menghindari kebingungan ( ini hanya masalah pilihan , tetapi karakteristik utama yang dilindungi adalah subkelas, jadi paket-pribadi lebih unggul), dan hasilnya , hanya 2 pengubah akses yang diizinkan di tingkat atas:
Di tingkat atas — publik, atau paket-pribadi (tanpa pengubah eksplisit).
Mendefinisikan field yang dilindungi membuat field itu dapat diakses di dalam paket maupun di luar paket hanya melalui pewarisan (Hanya di dalam kelas anak).
Jadi Jika kita diizinkan untuk membuat sebuah kelas diproteksi maka kita dapat mengaksesnya di dalam paket dengan sangat mudah tetapi untuk mengakses kelas itu di luar paket, pertama-tama kita perlu memperluas entitas di mana kelas ini didefinisikan, yaitu paketnya.
Dan karena sebuah paket tidak dapat diperpanjang (dapat diimpor), mendefinisikan kelas yang dilindungi akan membuatnya menjadi paket-privat yang mirip dengan mendefinisikannya sebagai default yang sudah dapat kita lakukan. Oleh karena itu tidak ada manfaatnya mendefinisikan kelas privat itu hanya akan membuat hal-hal menjadi ambigu.
Untuk informasi selengkapnya, baca Mengapa kelas luar Java tidak bisa dijadikan pribadi atau diproteksi
Dilindungi tidak mirip dengan publik. Protected memiliki kedua akses tingkat paket plus dapat diakses di luar paket hanya dengan pewarisan .. Jika kelas mengatakan A di luar paket MENGHARUSKAN kelas dari paket lain (dengan metode yang dilindungi dengan menggunakan INHERITANCE) ia dapat mengakses metode kelas B ini yang memiliki metode yang dilindungi tetapi sub-kelas yang diturunkan dari kelas ini yaitu, A tidak dapat mengakses metode yang dilindungi..kebalikannya terjadi dengan publik ..
Contoh:
package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
behavior "protected" = perilaku "default" + "menggunakannya di subclass mana pun di paket mana pun".
Bagaimanapun kita memiliki pengubah akses default untuk kelas, satu-satunya keuntungan yang dapat kita peroleh dari pengubah akses yang dilindungi adalah: - dengan menggunakannya dalam paket apa pun melalui subclassing. Tapi untuk subclass, visibilitas kelas induk "dilindungi" akan menjadi pribadi. Jadi tidak bisa diakses. Pada dasarnya jika Anda memiliki kelas tingkat atas yang dilindungi, tidak ada kelas luar yang dapat mengakses dengan membuat subkelasnya. Jadi terlindungi untuk kelas level atas tidak ada artinya.
Terlindung : TERLIHAT hanya ke tingkat paket *.
kelas didefinisikan dilindungi ---> itu tidak dapat diperpanjang dari paket luar (tidak terlihat).
Dan jika tidak bisa diperpanjang maka tidak ada artinya tetap dilindungi , karena akan menjadi default akses yang diijinkan.
Hal yang sama berlaku untuk kelas yang ditentukan pribadi .
Catatan: Kelas bersarang atau dalam dapat didefinisikan sebagai dilindungi atau privat .
* : Jelajahi kata kunci yang dilindungi , untuk jawaban ini saya membuatnya ringkas.
Jawaban dari @ Akash5288 tidak masuk akal bagi saya:
Jika semua kelas diizinkan untuk subkelas maka itu akan mirip dengan penentu akses publik.
Karena tidak ada cara untuk membatasi kelas ini menjadi subkelas hanya dengan beberapa kelas (kami tidak dapat membatasi kelas yang diwarisi hanya oleh beberapa kelas dari semua kelas yang tersedia dalam sebuah paket / di luar paket), tidak ada penggunaan penentu akses yang dilindungi untuk kelas tingkat atas. Oleh karena itu tidak diperbolehkan.
Anda kemudian dapat menerapkan logika yang sama ke metode dan variabel yang dilindungi, mereka juga "mirip dengan publik". Semua kelas di luar sebuah paket dapat memperluas kelas publik kita dan menggunakan metode terlindungnya. Mengapa membatasi metode dan variabel ke kelas yang diperluas tidak masalah, tetapi membatasi seluruh kelas tidak baik? "Mirip dengan publik" tidak "sama dengan publik". Interpretasi saya adalah bahwa tidak masalah untuk mengizinkan kelas yang dilindungi, karena tidak masalah untuk mengizinkan metode yang dilindungi.
Jawaban "Anda tidak dapat memperluas kelas yang tidak dapat Anda akses / lihat" lebih logis.
Apa yang masuk akal untuk pertanyaan ini adalah bahwa, JVM ditulis dalam C (Sun JVM) dan C ++ (oracle JVM) jadi selama kompilasi, kita akan membuat file .class dari file java kita dan jika kita mendeklarasikan kelas dengan kata kunci Protected maka tidak akan bisa diakses oleh JVM.
Jawaban mengapa kelas yang dilindungi tidak akan diakses oleh JVM adalah, karena bidang yang dilindungi dapat diakses dalam paket yang sama atau ke paket yang berbeda hanya melalui pewarisan dan JVM tidak ditulis sedemikian rupa sehingga ia akan mewarisi kelas kehendak. Semoga ini memenuhi pertanyaan ini :)
Demikian pula, kelas tingkat atas tidak boleh pribadi. Penjelasannya seperti di bawah ini:
Jadi apa yang akan terjadi jika kita akan mendefinisikan kelas privat, kelas itu hanya akan dapat diakses di dalam entitas di mana ia didefinisikan yang dalam kasus kita adalah paketnya?
Jadi mendefinisikan akses privat ke kelas akan membuatnya dapat diakses di dalam paket yang sama yang telah dilakukan oleh kata kunci default untuk kita, Oleh karena itu tidak ada manfaat dari mendefinisikan kelas privat itu hanya akan membuat hal-hal menjadi ambigu.
protected berarti bahwa anggota dapat diakses oleh kelas mana pun dalam paket yang sama dan oleh sub kelas bahkan jika mereka berada di paket lain.
Contoh:
package a;
class parent{
protected void p();
}
package b;
import a.p;
class child extends parent{
//you can access method which is protected in the parent in the child
}
class another extends child {
//here you can not access the protected method
}
jika kelas luar dideklarasikan oleh protected, saya rasa Anda ingin kelas itu hanya dapat diakses dari paket yang sama dan subkelasnya tetapi paket yang berbeda. Namun, subclass tidak mungkin dibuat untuk kelas yang dilindungi, karena ketika Anda menulis "kelas Anjing memperluas Hewan", karena "Hewan" yang dilindungi hanya dapat diakses oleh subkelasnya, jelas "Anjing" bukan subkelas "Hewan" .
Jadi kelas luar yang dilindungi sama dengan kelas luar (default)!