Mengapa kelas tidak dapat didefinisikan sebagai dilindungi?

91

Mengapa kita tidak bisa mendefinisikan kelas sebagai protected?

Aku tahu kita tidak bisa, tapi kenapa? Harus ada alasan khusus.

MJ
sumber
3
Apa yang akan dilakukannya jika Anda menyatakan kelas dilindungi?
1
Saya pikir inilah yang Anda cari: stackoverflow.com/questions/2534733/java-protected-classes : D
dewijones92
2
Anggap saja mengapa kelas luar tidak bisa dilindungi? Kelas-kelas dalam dapat dilindungi.
Number945

Jawaban:

102

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.

Nikita Rybak
sumber
> Karena tidak ada konsep seperti 'subpackage' atau 'package-inheritance' di Java, mendeklarasikan class protected atau package-private akan menjadi hal yang sama. Mengapa kelas yang dilindungi memiliki visibilitas yang sama dengan paket-pribadi? Bukankah itu sama dengan publik? Terima kasih.
yaromir
@Nikita Ryback Bisakah Anda menjelaskan Apa itu subPackage atau package-inheritance? Saya masih belum jelas mengapa dilindungi digunakan di kelas atas. Jika Anda menjelaskan dengan contoh itu akan sangat bagus.
App Kart
Ketika Anda mendeklarasikan anggota kelas sebagai dilindungi visibilitasnya adalah kelas pada paket yang sama (disebut akses paket) dan Subclassess . Jika Anda mencoba mengakses dari kelas outter dalam paket lain, anggota metode terlindungi ini tidak terlihat.
kelgwiin
@kelgwiin Saya yakin Anda tidak boleh mencampur pengubah akses kelas dan anggota. Karena keduanya berbeda. Sementara kelas memungkinkan dirinya untuk dimodifikasi sebagai publik atau default, anggota dapat dimodifikasi sebagai publik, privat, dilindungi dan default.
sharhp
2
"Karena tidak masuk akal" - itu pernyataan yang agak berani. Ini tidak didefinisikan di Java, tetapi hal serupa memang ada; misalnya opendi Kotlin yang mengizinkan subclassing di luar paket saat ini (bisa dibayangkan protecteddi Java mencegahnya, dengan default yang berlawanan).
Raphael
41

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:

  • kelas tingkat atas yang dilindungi akan terlihat oleh kelas-kelas dalam paketnya.
  • sekarang membuatnya terlihat di luar paket (subclass) agak membingungkan dan rumit. Kelas mana yang harus diizinkan untuk mewarisi kelas kami yang dilindungi?
  • Jika semua kelas diizinkan untuk subkelas maka itu akan mirip dengan penentu akses publik.
  • Jika tidak ada maka itu mirip dengan default.

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.

Akash5288
sumber
3
"sekarang membuat kelas yang dilindungi terlihat di luar paket (subkelas) agak membingungkan dan rumit. Kelas mana yang harus diizinkan untuk mewarisi kelas terlindungi kami? dan Jika semua kelas diizinkan untuk subkelas maka itu akan mirip dengan penentu akses publik." benar-benar membantu saya memahami masalah mengapa kelas yang dilindungi tidak masuk akal :)
user1338998
15
public class A
{
    protected class B
    {
    }
}
tak ternilai
sumber
3

@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 :

masukkan deskripsi gambar di sini

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:

masukkan deskripsi gambar di sini

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).

Buah
sumber
3

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

Naresh Joshi
sumber
3
Harap ungkapkan afiliasi apa pun dan jangan gunakan situs ini sebagai cara untuk mempromosikan situs Anda melalui posting. Lihat Bagaimana cara menulis jawaban yang baik? .
1

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
}
Shruthi reddy
sumber
0

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.

madhu
sumber
0

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.

Narendra Singh
sumber
0

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.

ks
sumber
0

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.

Anurag Prasad
sumber
0

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 
}
Yogesh Patil
sumber
0

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)!

Jeen Yung
sumber