Java'da genel, korumalı, paket-özel ve özel arasındaki fark nedir?


3171

Java'da, yani varsayılan (özel paket), erişim değiştiricileri her ne zaman kullanılacağı hakkında net kurallar vardır public, protectedve privateyaparken, classve interfaceve miras ile ilgili?


161
privatepaketteki diğer sınıflardan gizler. publicpaketin dışındaki sınıflara maruz kalır. yalnızca alt sınıflarla sınırlı protectedbir sürümüdür public.
Museful

87
@Tennenrishin - Hayır; C ++ 'ın aksine, Java'da protectedyöntemi tüm paketten de erişilebilir hale getirir. Java'nın görünürlük modelindeki bu aptallık hedefi kırıyor protected.
Nicolas Barbulesco

35
@Nicolas Tüm pakette, olsun veya olmasın erişilebilir protected. Bir erişim değiştirici olarak , tek protectedyapmanız gereken paketin dışındaki alt sınıflara maruz kalmaktır.
Mart'ta Museful

15
@tennenrishin - evet, Nicolas bunu söyledi ... ve şimdi tekrarlıyorsun. Ne başlangıçta söyledi olmasıydı protected- ve teklif - korumalı beri kendi de itiraf doğru değildir ergo, o değil (aynı zamanda bütün paketi içinden erişim sağlar 'Yalnızca alt sınıflara sınırlı halkın bir sürümüdür' kısıtlamak alt sınıflara erişimi. )
luis.espinal

10
Ayrıca Nicolas ile Java'daki korumalı erişim modunun aptalca olduğu konusunda hemfikirim. Olan şey Java'nın yatay (kafes) ve dikey erişim kısıtlama niteleyicileri ile sınırlı olmasıdır. Varsayılan kapsam, kafesin paket olduğu yatay / kafes kısıtlamasıdır. Kamu, kafesin tüm dünya olduğu başka bir yatay kısıtlamadır. Özel ve (C ++) korumalı dikeydir. Diyelim ki, protected-packagegerçekten ihtiyaç duyduğumuz nadir durumlarda protected, korumalı C ++ sürümüne eşdeğer bırakarak , çapraz erişimimiz olsaydı daha iyi olurdu .
luis.espinal

Yanıtlar:


5637

Resmi öğretici sizin için yararlı olabilir.

______________________________________________________________
| │ Sınıf │ Paket │ Alt sınıf │ Alt sınıf │ Dünya |
| Same │ │ (aynı pkg) │ (fark pkg) │ |
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| kamu │ + │ + │ + │ + │ + | 
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| korumalı │ + │ + │ + │ + │ | 
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| değiştirici yok│ + │ + │ + │ │ | 
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| özel │ + │ │ │ │ |
| ___________ | _______ | _________ | __________ | __________ | ________ |
 +: erişilebilir boş: erişilebilir değil

5
privateÜyeler bile aynı kaynak dosyadaki herhangi bir sınıf / statik yöntemle görülebildiği / kullanılabildiği için yukarıdaki tablo yanlıştır .
Usagi Miyamoto

5
Korunan üyeye yalnızca aynı paketin alt sınıfından erişilebilir, ancak farklı paketin alt sınıfından erişilemez. Yukarıdaki tabloda bir düzeltme olmalıdır
niks

2
Dünya projenizde . Daha fazla açıklamalıyım. Kütüphaneler projeniz dahilindedir ve bir kütüphane oluşturuyorsanız, bu ortak sınıfları ve yöntemleri de ortaya koyarlar. Yani, sadece projeniz dahilinde söylemek biraz kapalı. "Onu kullanan her şey" daha iyi bir tanımdır.
adprocas

3
Örneğin, eğer varsa MyClassve yapıyorsam AnotherClass extends MyClassiçeriden tüm korunan ve herkese açık yöntemlere ve özelliklere erişimim olacak AnotherClass. Ben yaparsam MyClass myClass = new MyClass();içinde AnotherClassyerde - let yapıcısını söylemek - bu farklı bir pakette ise sadece kamu yöntemlere erişebilecek. Bunu yaparsam = new MyClass() { @Override protected void protectedMethod() { //some logic } };korumalı yöntemlere erişebileceğimi, ancak bu tür genişletme ile aynı şekilde olduğunu, ancak bunun yerine satır içi olarak göründüğünü unutmayın.
adprocas

3
Ne yazık ki, bu cevap kaba bir aşırı basitleştirmedir. Gerçeklik, özellikle düşündüğünüzde protected(aslında tam olarak anlaşılması oldukça zor bir erişim değiştiricidir - protectedgerçekten ne anlama geldiğini bildiklerini düşünen çoğu insan) biraz daha karmaşıktır . Ayrıca, Bohemian'ın işaret ettiği gibi, soruya cevap vermez - her erişim değiştiricinin ne zaman kullanılacağı hakkında hiçbir şey söylemez . Bence, bu çözüm değil oldukça kötü downvote için yeterli, ama yakın. Ama 4000'den fazla upvotes? Bu nasıl oldu?
Dawood ibn Kareem

483

(Dikkat: Ben bir Java programcısı değilim, ben bir Perl programcısıyım. Perl resmi bir korumaya sahip değil, belki de bu yüzden sorunu çok iyi anlıyorum :))

Özel

Düşündüğünüz gibi, sadece ilan edildiği sınıf onu görebilir.

Özel Paket

Sadece beyan edildiği paket tarafından görülebilir ve kullanılabilir . Bu, Java'daki varsayılan değerdir (bazıları hata olarak görür).

korumalı

Private + paketi alt sınıflar veya paket üyeleri tarafından görülebilir.

halka açık

Herkes görebilir.

Yayınlanan

Kontrol ettiğim kodun dışında görülebilir. (Java sözdizimi olmasa da, bu tartışma için önemlidir).

C ++, "arkadaş" adlı ek bir seviye tanımlar ve bu konuda ne kadar az bilgi sahibi olursanız o kadar iyi olur.

Ne zaman kullanmalısın? Bütün fikir bilgiyi gizlemek için kapsüllemedir. Mümkün olduğunca kullanıcılarınızdan bir şeyin nasıl yapıldığının ayrıntılarını gizlemek istersiniz. Neden? Çünkü daha sonra bunları değiştirebilir ve kimsenin kodunu kırmayabilirsiniz. Bu, birisinin elden geçirdiğiniz kodu kullandığından endişe etmeden hataları optimize etmenizi, yeniden düzenlemenizi, yeniden tasarlamanızı ve düzeltmenizi sağlar.

Dolayısıyla, temel kural, şeyleri olması gerektiği kadar görünür kılmaktır. Özel ile başlayın ve yalnızca gerektiğinde daha fazla görünürlük ekleyin. Sadece kullanıcının bilmesi için kesinlikle gerekli olanı herkese açık hale getirin, herkese açık yaptığınız her ayrıntı sistemi yeniden tasarlama yeteneğinizi artırır.

Kullanıcıların, içselleri onları geçersiz kılabilmeleri için herkese açık hale getirmek yerine davranışları özelleştirebilmelerini istiyorsanız, bu cesaretleri bir nesneye itmek ve bu arabirimi herkese açık hale getirmek daha iyi bir fikirdir. Bu şekilde yeni bir nesne ekleyebilirler. Örneğin, bir CD çalar yazıyorsanız ve bu yöntemleri herkese açık hale getirmek yerine "bu CD hakkında bilgi bul" bitinin özelleştirilebilir olmasını istiyorsanız, tüm bu işlevleri kendi nesnesine koyar ve yalnızca nesne alıcı / ayarlayıcınızı herkese açık hale getirirsiniz . Bu şekilde bağırsaklarınızı ortaya çıkarmak konusunda cimri olmak endişelerin iyi kompozisyonunu ve ayrılmasını teşvik eder

Şahsen ben sadece "özel" ve "herkese açık" diyorum. Birçok OO dili sadece buna sahiptir. "Korumalı" kullanışlı olabilir, ama gerçekten bir hile. Bir arayüz özel olmaktan çok daha fazlası, kontrolünüz dışındadır ve kullanımları bulmak için başkalarının koduna bakmanız gerekir.

Burada "yayınlanmış" fikri devreye giriyor. Bir arayüzün değiştirilmesi (yeniden düzenlenmesi) onu kullanan tüm kodu bulmanızı ve bunu değiştirmenizi gerektiriyor. Arayüz özelse, sorun değil. Eğer korunuyorsa tüm alt sınıflarınızı bulmalısınız. Herkese açıksa, kodunuzu kullanan tüm kodu bulmanız gerekir. Bazen bu mümkündür, örneğin, dahili kullanım için olan şirket kodu üzerinde çalışıyorsanız, yalnızca bir arabirimin herkese açık olması önemli değildir. Tüm kodu şirket havuzundan alabilirsiniz. Ama eğer bir arayüz "yayınlanmışsa", kontrolünüz dışında onu kullanan bir kod varsa, o zaman orada kalırsınız. Bu arayüzü veya risk kırma kodunu desteklemelisiniz. Korumalı arayüzler bile yayınlanmış olarak kabul edilebilir (bu yüzden

Birçok dil, kamusal / korumalı / özelin hiyerarşik doğasını gerçeklikle uyumlu değil, çok sınırlayıcı bulmaktadır. Bu amaçla, bir özellik sınıfı kavramı var , ama bu başka bir gösteri.


26
arkadaşlar -> "Ne kadar az bilirseniz o kadar iyi" ---> Paket gizliliğinden hala üstün olan seçici görünürlük sağlar. C ++ 'da, kullanımları vardır, çünkü tüm işlevler üye işlevler olamaz ve arkadaşlar herkesten daha iyidir. Elbette kötü zihinlerin yanlış kullanım tehlikesi vardır.
Sebastian Mach

30
Ayrıca, C ++ 'daki "korumalı" nın farklı bir anlamı olduğu da belirtilmelidir - korumalı bir yöntem etkili bir şekilde özeldir, ancak yine de miras kalan bir sınıftan çağrılabilir. (Java'nın aksine, aynı paket içindeki herhangi bir sınıf tarafından çağrılabilir.)
Rhys van der Waerden

9
@RhysvanderWaerden C #, bu açıdan C ++ ile aynıdır. Java'nın alt sınıfa erişilebilen bir üyeyi bildirmesine izin vermediği, ancak tüm paketin bulunmadığı oldukça garip buluyorum. Bana biraz ters düşüyor - bir paket çocuk sınıfından daha geniş bir kapsam!
Konrad Morawski

15
@KonradMorawski IMHO paketi alt sınıftan daha küçük bir kapsamdır. Sınıfınızı final olarak ilan etmediyseniz, kullanıcılar sınıfın alt sınıfını alabilmelidir - bu nedenle java korumalı, yayınlanan arayüzünüzün bir parçasıdır. OTOH, paketler dolaylı olarak tek bir kuruluş tarafından geliştirilir: örn. Com.mycompany.mypackage. Kodunuz paketimde kendini beyan ederse, kendinizi kuruluşumun bir parçası olarak dolaylı olarak ilan edersiniz, bu yüzden iletişim kurmalıyız. Böylece paket, alt sınıfa (nesnemi genişleten kişilere) göre daha küçük / daha kolay bir kitleye (şirketimdeki kişiler) yayınlar ve bu nedenle daha düşük görünürlük olarak sayılır.
İsimsiz

2
friendsınıflar arasındaki özel ilişkileri tanımlamak için iyidir. Doğru kullanıldığında birçok durumda üstün kapsüllemeye izin verir. Örneğin, ayrıcalıklı bir fabrika sınıfı tarafından, dahili bağımlılıkları yapılandırılmış bir türe enjekte etmek için kullanılabilir. Kötü bir adı var, çünkü iyi tasarlanmış bir nesne modelini doğru bir şekilde korumakla ilgilenmeyen insanlar iş yükünü hafifletmek için onu kötüye kullanabilirler.
Dennis

434

İşte tablonun modüller için bir sütun içeren daha iyi bir sürümü.

Java Erişim Değiştiricileri

açıklamalar

  • Bir özel üye ( i) 'dir sadece o ilan edilir aynı sınıfta içinde erişilebilir.

  • Erişim değiştiricisi ( j) bulunmayan bir üyeye yalnızca aynı paketteki sınıflardan erişilebilir.

  • Bir korunmuş elemanı ( k) aynı paket içinde tüm sınıfları içinde erişilebilir ve diğer paketlerde alt sınıflar içindeki.

  • Bir ortak üye ( l) tüm sınıflar tarafından erişilebilir ( bildirildiği paketi dışa aktarmayan bir modülde bulunmuyorsa).


Hangi değiştiriciyi seçmelisiniz?

Erişim değiştiriciler, yanlışlıkla kapsüllenmeyi (*) engellemenize yardımcı olan bir araçtır . Üyeye sınıf, paket, sınıf hiyerarşisinde dahili olan veya hiç dahili olmayan bir şey olup olmayacağınızı sorun ve buna göre erişim düzeyini seçin.

Örnekler:

  • Bir alan long internalCounterdeğiştirilebilir ve bir uygulama detayı olduğu için büyük olasılıkla özel olmalıdır.
  • Yalnızca fabrika sınıfında (aynı pakette) başlatılması gereken bir sınıfın, paketle sınırlı bir kurucuya sahip olması gerekir, çünkü onu doğrudan paketin dışından çağırmak mümkün olmamalıdır.
  • Oluşturulmadan void beforeRender()hemen önce adlandırılan ve alt sınıflarda kanca olarak kullanılan dahili bir yöntem korunmalıdır.
  • void saveGame(File dst)GUI kodundan çağrılan bir yöntem herkese açık olmalıdır.

(*) Kapsülleme tam olarak nedir?


11
Sadece şunu söylüyorum: kırmızı / yeşil renklendirmeyi ayırt etmekte sorun yaşayan birçok insan var. Kırmızı / yeşil (veya sarı / turuncu / ...) boyama şemalarını kullanan tablolar nadiren her şeyde "daha iyi" ;-)
GhostCat

1
@GhostCat, katılmıyorum. Birçok insan için "işler" / "değil iş" ile sezgisel kırmızı / yeşil Uyum Gösterir düşünüyorum yani o olduğunu daha iyi birçok alternatiflere göre.
aioobe

8
colourblindawareness.org/colour-blindness/... ... Renk körü erkeklerin% 8'i% 1 deuteranopes,% 1 protanopes,% 1 protanomalous ve içine yaklaşık ayrılabilir % 5 deuteranomalous . Ve bu% 5'in% 50'sinden biri olduğumdan emin olabilirsiniz: kırmızı / yeşil berbat.
GhostCat

6
@GhostCat Tamam .. bu nüfusun beklediğimden daha büyük bir parçası. Görüntüyü bu renk körlüğü simülatörüne yükledim ve tüm farklı modları test ettim . Tek renkli / akromatopsi modunda bile renk farkı mantıklıdır. Farkı görebiliyor musunuz veya simülatör kapalı mı? (Hala kırmızı / yeşilin insanları görmek için çok sezgisel olduğunu düşünüyorum.)
aioobe

3
Farkı görebiliyorum, ancak sürücü lisansı ;-) için Almanya'da yapmamız gereken renk körlüğü testlerinin yarısını da geçebiliyorum ama bence böyle bir simülatör "yeterince iyi".
GhostCat

206
____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |              |          |              |     
————————————————+———————————————+———————————+———————————————+———————
protected       |              |          |              |      
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |              |          |              |      
————————————————+———————————————+———————————+———————————————+———————
private         |              |          |              |       
____________________________________________________________________

1
Sözde ifade etmekte fayda var - "Korumalı değiştirici nesneyi diğer paketler arasında kullanılabilir hale getirirken, varsayılan / değiştirici aynı pakete erişimi kısıtlıyor"
vanguard69

2
@ vanguard69, protecteddeğiştirici, işaretli şeyi (sınıf, yöntem veya alan) başka bir pakette başka bir sınıf için kullanılabilir kılarsa , diğer sınıf, bu protectedişaretli şeyin bildirildiği sınıfın bir alt sınıfıdır .
Abdull

"nonsubbed"? "bu alt sınıf başka bir pakette"? Huh. Java'yı tanıdığımı sanıyordum.
17'de

@AlexanderFarber belirli bir tarayıcı yapılandırması için optimize ettiniz mi? Bu benim
kromum

Hmm o zaman değişimimi geri alalım
Alexander Farber

165

Kolay kural. Her şeyi özel ilan ederek başlayın. Ve sonra ihtiyaçlar ortaya çıktıkça ve tasarım gerektiğinde halka doğru ilerler.

Üyeleri ortaya koyarken kendinize temsil seçeneklerini veya soyutlama seçeneklerini gösterip göstermediğinizi sorun. Birincisi, kaçınılması gereken bir şeydir, çünkü gözlemlenebilir davranışı yerine gerçek temsile çok fazla bağımlılık getirecektir.

Genel bir kural olarak, alt sınıflandırma yoluyla yöntem uygulamalarını geçersiz kılmaya çalışmamaya çalışıyorum; mantığı sıkıştırmak çok kolay. Geçersiz kılmayı düşünüyorsanız soyut korumalı yöntemler bildirin.

Ayrıca, elden geçirdiğinizde bir şeyin kırılmasını önlemek için geçersiz kılma sırasında @ Override ek açıklamasını kullanın.


3
@RuchirBaronia, "world" = nerede olursa olsun uygulamadaki tüm kodlar.
Andrejs

116

Aslında basit bir ızgaradan biraz daha karmaşık. Izgara size bir erişime izin verilip verilmediğini söyler, ancak tam olarak bir erişimi ne oluşturur? Ayrıca, erişim düzeyleri, iç içe sınıflarla ve kalıtımla karmaşık yollarla etkileşime girer.

"Varsayılan" erişim (bir anahtar kelimenin yokluğunda belirtilen) paket-özel olarak da adlandırılır . İstisna: bir arayüzde hiçbir değiştirici genel erişim anlamına gelir; kamu dışında değiştiriciler yasaktır. Enum sabitleri her zaman herkese açıktır.

özet

Bu erişim belirleyicisiyle bir üyeye erişime izin veriliyor mu?

  • Üye private: Yalnızca üye çağrı koduyla aynı sınıfta tanımlanmışsa.
  • Üye paket özeldir: Yalnızca çağıran kod üyenin hemen çevresindeki paketin içindeyse.
  • Üye protected: Aynı paket veya üye, çağıran kodu içeren sınıfın bir üst sınıfında tanımlanmışsa.
  • Üye public: Evet.

Hangi erişim belirleyicileri için geçerlidir?

Yerel değişkenler ve biçimsel parametreler erişim belirteçlerini alamaz. Kapsam belirleme kurallarına göre doğal olarak dışa erişilemedikleri için etkin bir şekilde özeldirler.

Üst kapsamdaki sınıflar için yalnızca publicve pakete özel izin verilir. Bu tasarım tercihi muhtemelen çünkü protectedve privatepaket düzeyinde gereksiz olurdu (paketlerin miras yoktur).

Tüm erişim belirteçleri sınıf üyelerinde (yapıcılar, yöntemler ve statik üye işlevleri, iç içe sınıflar) mümkündür.

İlgili: Java Sınıfı Erişilebilirliği

Sipariş

Erişim belirteçleri kesinlikle sipariş edilebilir

herkese açık> korumalı> özel paket> özel

yani publicen privateaz , en çok erişimi sağlar . Özel bir üye üzerinde yapılabilecek herhangi bir referans, paket-özel üye için de geçerlidir; paket-özel üyeye yapılan herhangi bir başvuru, korunan bir üye için geçerlidir, vb. (Korunan üyelere aynı paketteki diğer sınıflara erişim izni vermek bir hata olarak değerlendirildi.)

notlar

  • Bir sınıfın yöntemleri vardır aynı sınıfın diğer nesnelerin özel üyelerini erişmesine olanak tanıdı. Daha kesin olarak, bir C sınıfı yöntemi, C'nin herhangi bir alt sınıfındaki nesneler üzerindeki C'nin özel üyelerine erişebilir. Java, örneğin sınıf yoluyla erişimi kısıtlamayı desteklemez. (Kullanarak destekleyen Scala ile karşılaştırın private[this].)
  • Bir nesne oluşturmak için bir kurucuya erişmeniz gerekir. Dolayısıyla, tüm kurucular özelse, sınıf yalnızca sınıf içinde yaşayan kodlarla oluşturulabilir (tipik olarak statik fabrika yöntemleri veya statik değişken başlatıcılar). Benzer şekilde paket-özel veya korumalı kurucular için.
    • Yalnızca özel yapıcılara sahip olmak, sınıfın harici olarak alt sınıflara ayrılamayacağı anlamına gelir, çünkü Java bir alt sınıfın yapıcılarının örtülü veya açık bir şekilde bir üst sınıf yapıcısını çağırmasını gerektirir. (Ancak, alt sınıfları içeren bir iç içe sınıf içerebilir.)

İç sınıflar

Ayrıca iç sınıflar gibi iç içe kapsamları da göz önünde bulundurmalısınız . Karmaşıklığın bir örneği, iç sınıfların, erişim değiştiricileri alabilecek üyelere sahip olmasıdır. Böylece bir kamu üyesi ile özel bir iç sınıfa sahip olabilirsiniz; üye erişilebilir mi? (Aşağıya bakın.) Genel kural, kapsama bakmak ve her seviyeye erişip erişemeyeceğinizi görmek için tekrar tekrar düşünmektir.

Ancak, bu oldukça karmaşıktır ve tüm ayrıntılar için Java Dil Belirtimi'ne bakın . (Evet, geçmişte derleyici hataları vardı.)

Bunların nasıl etkileştiklerinin bir tadı için bu örneği düşünün. Özel iç sınıfları “sızdırmak” mümkündür; bu genellikle bir uyarıdır:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

Derleyici çıktısı:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

İlgili bazı sorular:


1
"genel dışındaki değiştiriciler yasaktır" - Java 9'dan itibaren, durum artık böyle değil: arayüzlerin özel yöntemleri de olabilir.
MC İmparatoru

96

Kural olarak:

  • private: sınıf kapsamı.
  • default(veya package-private): paket kapsamı.
  • protected: package scope + child(paket gibi, ancak farklı paketlerden alt sınıflandırabiliriz). Korumalı değiştirici her zaman "üst-alt" ilişkisini korur.
  • public: her yerde.

Sonuç olarak, erişim hakkını üç hakka bölersek:

  • (D) irect (aynı sınıftaki bir yöntemden veya "bu" sözdizimi yoluyla çağrılır ).
  • (R) tercihi (sınıfa başvuru kullanarak veya "nokta" sözdizimi yoluyla bir yöntemi çağırır).
  • (I) kalıtım (alt sınıflandırma yoluyla).

o zaman bu basit tabloya sahibiz:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+

54

Kısacası

  • public: her yerden erişilebilir.
  • protected: aynı paketin sınıfları ve herhangi bir pakette bulunan alt sınıflar tarafından erişilebilir.
  • varsayılan (değiştirici belirtilmedi): aynı paketin sınıfları tarafından erişilebilir.
  • private: yalnızca aynı sınıfta erişilebilir.

48

Java'da en yanlış anlaşılan erişim değiştirici protected. Alt sınıfların görebileceği bir istisna dışında varsayılan değiştiriciye benzer olduğunu biliyoruz. Ama nasıl? İşte karışıklığı umarım açıklayan bir örnek:

  • 2 sınıfımız olduğunu varsayın; Fatherve Sonher biri kendi paketinde:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
  • En protected yöntem ekleyelim foo()için Father.

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
  • Yöntem foo()4 bağlamda çağrılabilir:

    1. foo()Tanımlanan aynı pakette bulunan bir sınıfın içinde ( fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
    2. Bir alt sınıfın içinde, geçerli örnekte thisveya aracılığıyla super:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
    3. Türü aynı sınıf olan bir başvuruda:

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
    4. Türü üst sınıf olan ve tanımlanmış olan paketin ( ) içindeki bir başvuruda [Bu, bağlam no. 1]:foo()fatherpackage

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
  • Aşağıdaki durumlar geçerli değildir.

    1. Türü üst sınıf olan ve tanımlanmış ( ) paketinin dışında olan bir başvuruda :foo()fatherpackage

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
    2. Bir alt sınıf paketinin içindeki alt sınıf olmayan (Bir alt sınıf, korunan üyeleri üst öğesinden devralır ve alt sınıf olmayanlara özel yapar):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }

Object#clone()protectedüyeye bir örnektir .
Eng.Fouad

Yapma ile super.foo()ilk geçersiz durum arasındaki fark nedir f.foo()?
cst1992

1
@ cst1992 Kafa karıştırıcı ancak Java Dil Spesifikasyonu 6.6.2: "Bir nesnenin korumalı bir üyesine veya yapıcısına, yalnızca o nesnenin uygulanmasından sorumlu olan kodla bildirildiği paketin dışından erişilebilir". Super.foo () ile "super" referansı "uygulamadan doğrudan sorumludur", ancak "f" referansı değildir. Neden? Çünkü "süper" nin Baba türünde olduğundan% 100 emin olabilirsiniz, "f" için değil; çalışma zamanında başka bir Baba alt türü olabilir. Bkz. Docs.oracle.com/javase/specs/jls/se9/html/…
skomisa

1
Anlayan birinin cevabını okumak canlandırıcı protected. Ne yazık ki, bu sayfadaki diğer tüm cevaplar protectedonu biraz yanlış anlıyor.
Dawood ibn Kareem

30

Özel

  • Yöntemler, Değişkenler ve Yapıcılar

Özel olarak bildirilen Yöntemler, Değişkenler ve Yapıcılara yalnızca bildirilen sınıfın içinden erişilebilir.

  • Sınıf ve Arayüz

Özel erişim değiştirici en kısıtlayıcı erişim seviyesidir. Sınıf ve arayüzler özel olamaz.

Not

Özel olarak bildirilen değişkenlere, sınıfta genel alıcı yöntemleri varsa sınıf dışında erişilebilir. Bir üst sınıfta korunduğu bildirilen değişkenlere, yöntemlere ve kuruculara yalnızca diğer paketteki alt sınıflar veya korunan üye sınıfının paketi içindeki herhangi bir sınıf tarafından erişilebilir.


korumalı

  • Sınıf ve Arayüz

Korumalı erişim değiştirici, sınıfa ve arabirimlere uygulanamaz.

Yöntemler, alanlar korumalı olarak ilan edilebilir, ancak bir arabirimdeki yöntemler ve alanlar korumalı olarak ilan edilemez.

Not

Korumalı erişim, alt sınıfa yardımcı yöntem veya değişkeni kullanma şansı verirken, ilgisiz bir sınıfın bunu kullanmaya çalışmasını engeller.


halka açık

Herkese açık olarak bildirilen bir sınıfa, yönteme, kurucuya, arabirime vb. Başka herhangi bir sınıftan erişilebilir.

Bu nedenle, ortak bir sınıf içinde bildirilen alanlara, yöntemlere, bloklara Java Evrenine ait herhangi bir sınıftan erişilebilir.

  • Farklı Paketler

Ancak, erişmeye çalıştığımız genel sınıf farklı bir pakedeyse, genel sınıfın içe aktarılması gerekir.

Sınıf mirası nedeniyle, bir sınıfın tüm genel yöntemleri ve değişkenleri alt sınıfları tarafından miras alınır.


Varsayılan -Anahtar kelime yok:

Varsayılan erişim değiştirici, bir sınıf, alan, yöntem vb. İçin açıkça bir erişim değiştirici bildirmediğimiz anlamına gelir.

  • Aynı Paketler İçinde

Erişim denetimi değiştiricisi olmadan bildirilen bir değişken veya yöntem, aynı paketteki diğer sınıflar tarafından kullanılabilir. Bir arabirimdeki alanlar dolaylı olarak genel statik sonlandırılır ve arabirimdeki yöntemler varsayılan olarak geneldir.

Not

Statik alanları geçersiz kılamayız. Geçersiz kılmaya çalışırsanız herhangi bir hata göstermez, ancak bizim dışında ne işe yaramazsa.

İlgili Cevaplar

Referans bağlantıları

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm


21

Fark, halihazırda sağlanan bağlantılarda bulunabilir ancak hangisinin kullanılacağı genellikle "En Az Bilgi Prensibi" ne iner. Yalnızca gereken en az görünürlüğe izin verin.


20

Özel : Yalnızca sınıfa sınırlı erişim

Varsayılan (değiştirici yok) : Sınıf ve pakete sınırlı erişim

Korumalı : Sınıf, paket ve alt sınıflara sınırlı erişim (paketin içinde ve dışında)

Genel : Sınıf, paket (tümü) ve alt sınıflara erişilebilir ... Kısacası, her yerde.


17

Erişim değiştiricileri, erişimi çeşitli düzeylerde kısıtlamak için vardır.

Genel: Temelde, aynı paket içinde olsun ya da olmasın, herhangi bir sınıftan erişebileceğiniz kadar basittir.

Aynı pakette bulunuyorsanız erişmek için doğrudan erişebilirsiniz, ancak başka bir pakette bulunuyorsanız, sınıfın bir nesnesini oluşturabilirsiniz.

Varsayılan: Aynı pakette herhangi bir sınıftan erişilebilir.

Erişmek için sınıfın bir nesnesini oluşturabilirsiniz. Ancak bu değişkene paketin dışında erişemezsiniz.

Korumalı: Değişkenlere aynı paketin yanı sıra başka bir paketin alt sınıfına erişebilirsiniz. temelde varsayılan + Devralınan davranıştır.

Temel sınıfta tanımlanan korumalı alana erişmek için alt sınıf nesnesi oluşturabilirsiniz.

Özel: aynı sınıfta erişim olabilir.

Statik olmayan yöntemlerde, bu başvuru nedeniyle (kurucularda da) doğrudan erişebilirsiniz, ancak statik yöntemlere erişmek için sınıfın nesnesini oluşturmanız gerekir.


16

Java'da değiştiricilere erişin.

Java erişim değiştiricileri, Java'da erişim denetimi sağlamak için kullanılır.

1. Varsayılan:

Yalnızca aynı paketteki sınıflara erişilebilir.

Örneğin,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

Bu erişim herkese açık ve korumalı olmakla birlikte özel olanlardan daha az kısıtlıdır.

2. Kamu

Her yerden erişilebilir. (Global Erişim)

Örneğin,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

Çıktı: Merhaba

3. Özel

Yalnızca aynı sınıf içinde erişilebilir.

Eğer bir sınıfta özel üyelere erişmeye çalışırsanız başka bir derleme hatası verir. Örneğin,

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4. Korumalı

Yalnızca aynı paketteki sınıflara ve alt sınıflara erişilebilir

Örneğin,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

Çıktı: Merhaba

Resim açıklamasını buraya girin


14
  • genel - uygulamanın herhangi bir yerinden erişilebilir.

  • varsayılan - paketten erişilebilir.

  • korumalı - paketten ve diğer paketteki alt sınıflardan erişilebilir. ayrıca

  • özel - yalnızca sınıfından erişilebilir.


14

Pakete görünür. Varsayılan. Değiştirici gerekmez.

Sadece sınıfa görünür ( özel ).

Dünyaya görünür ( halka açık ).

Pakete ve tüm alt sınıflara görünür ( korumalı ).

Değişkenler ve yöntemler çağrılan herhangi bir değiştirici olmadan bildirilebilir. Varsayılan örnekler:

String name = "john";

public int age(){
    return age;
}

Özel erişim değiştirici - özel:

Özel olarak bildirilen yöntemlere, değişkenlere ve kuruculara yalnızca bildirilen sınıfın içinden erişilebilir. Özel erişim değiştirici en kısıtlayıcı erişim düzeyidir. Sınıf ve arayüzler özel olamaz.

Özel olarak bildirilen değişkenlere, sınıfta genel alıcı yöntemleri varsa sınıf dışında erişilebilir.

Özel değiştiriciyi kullanmak, bir nesnenin kendisini kapsadığı ve dış dünyadan verileri gizlediği ana yoldur.

Örnekler:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

Genel erişim değiştirici - genel:

Herkese açık olarak bildirilen bir sınıfa, yönteme, kurucuya, arabirime vb. Başka herhangi bir sınıftan erişilebilir. Bu nedenle, bir ortak sınıf içinde bildirilen alanlara, yöntemlere, bloklara Java evrenine ait herhangi bir sınıftan erişilebilir.

Ancak, erişmeye çalıştığımız genel sınıf farklı bir pakedeyse, genel sınıfın içe aktarılması gerekir.

Sınıf mirası nedeniyle, bir sınıfın tüm genel yöntemleri ve değişkenleri alt sınıfları tarafından miras alınır.

Misal:

public void cal(){

}

Korumalı erişim değiştirici - korumalı:

Bir üst sınıfta korunduğu bildirilen değişkenlere, yöntemlere ve kuruculara yalnızca başka bir paketteki alt sınıflar veya korumalı üye sınıfının paketi içindeki herhangi bir sınıf tarafından erişilebilir.

Korumalı erişim değiştirici, sınıfa ve arabirimlere uygulanamaz. Yöntemler, alanlar korumalı olarak ilan edilebilir, ancak bir arabirimdeki yöntemler ve alanlar korumalı olarak ilan edilemez.

Korumalı erişim, alt sınıfa yardımcı yöntem veya değişkeni kullanma şansı verirken, ilgisiz bir sınıfın bunu kullanmaya çalışmasını engeller.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

12

Bu sayfa korumalı ve varsayılan erişim değiştirici hakkında iyi yazıyor

.... Korumalı: Korumalı erişim değiştirici biraz zor ve varsayılan erişim değiştiricinin bir üst kümesi olduğunu söyleyebiliriz. Korumalı üyeler, aynı paketteki erişim söz konusu olduğunda varsayılan üyelerle aynıdır. Fark, korunan üyelere, üyenin bildirildiği sınıfın, ana sınıfın bulunduğu paketin dışında olan alt sınıfları tarafından da erişilebilir olmasıdır.

Ancak bu korunan üyelere “paketin dışına yalnızca miras yoluyla erişilebilir”. yani, bir sınıfın korumalı bir üyesine, başka bir pakette bulunan alt sınıfında, üye alt sınıfın kendisinde varmış gibi doğrudan erişebilirsiniz. Ancak bu korunan üyeye, üst sınıfın başvurusu kullanılarak paketin dışındaki alt sınıfta erişilemez. ....


Sadece bunu eklemek için "Çocuk ana sınıfın korumalı üyesine eriştiğinde, alt sınıfın özel üyesi olur (ya da alt sınıfın alt sınıfları tarafından devralınabilen özel bir özel üye diyebilirim."
Anand

9

David'in yanıtı, her erişim değiştiricinin anlamını sağlar. Her birinin ne zaman kullanılacağına gelince, tüm sınıfları ve her sınıfın harici kullanım (API) ve diğer her şeyi özel amaçlı yöntemlerini herkese açık hale getirmenizi öneririm.

Zamanla, bazı sınıfların ne zaman özel hale getirileceği ve alt sınıflarda kullanılmak üzere korunan belirli yöntemlerin ne zaman bildirileceği konusunda bir fikir geliştireceksiniz.


6

Not: Bu sadece kabul edilen cevap için bir tamamlayıcıdır .

Bu, Java Erişim Değiştiricileri ile ilgilidir .

Gönderen Java Erişim Modifikörleri :

Java erişim değiştiricisi, hangi sınıfların belirli bir sınıfa ve onun alanlarına, yapıcılarına ve yöntemlerine erişebileceğini belirtir. Erişim değiştiricileri bir sınıf, yapıcıları, alanları ve yöntemleri için ayrı ayrı belirtilebilir. Java erişim değiştiricileri bazen günlük konuşmada Java erişim belirteçleri olarak da adlandırılır, ancak doğru ad Java erişim değiştiricileridir. Sınıflar, alanlar, oluşturucular ve yöntemler dört farklı Java erişim değiştiricisinden birine sahip olabilir:

  • Liste öğesi
  • özel
  • varsayılan (paket)
  • korumalı
  • halka açık

Gönderen Sınıf Üyelerine Kontrol Erişim öğreticiler:

Erişim düzeyi değiştiricileri, diğer sınıfların belirli bir alanı kullanıp kullanamayacağını veya belirli bir yöntemi çağırabileceğini belirler. İki seviye erişim kontrolü vardır:

  • En üst düzeyde — genel veya paket-özel (açık değiştirici yok).
  • Üye düzeyinde - genel, özel, korumalı veya paket-özel (açık değiştirici yok).

Bir sınıf değiştirici public ile bildirilebilir, bu durumda bu sınıf her yerdeki tüm sınıflar tarafından görülebilir. Bir sınıfın değiştiricisi yoksa (varsayılan, paket-özel olarak da bilinir), yalnızca kendi paketinde görünür

Aşağıdaki tabloda, her değiştiricinin izin verdiği üyelere erişim gösterilmektedir.

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
 Modifier     Class  Package  Subclass  World 
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
 public       Y      Y        Y         Y     
 protected    Y      Y        Y         N     
 no modifier  Y      Y        N         N     
 private      Y      N        N         N     
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

İlk veri sütunu, sınıfın kendisinin erişim düzeyi tarafından tanımlanan üyeye erişimi olup olmadığını gösterir. Gördüğünüz gibi, bir sınıfın her zaman kendi üyelerine erişimi vardır. İkinci sütun, sınıfla aynı paketteki sınıfların (ebeveynliklerinden bağımsız olarak) üyeye erişimi olup olmadığını gösterir. Üçüncü sütun, bu paketin dışında bildirilen sınıfın alt sınıflarının üyeye erişimi olup olmadığını gösterir. Dördüncü sütun, tüm sınıfların üyeye erişimi olup olmadığını gösterir.

Erişim seviyeleri sizi iki şekilde etkiler. İlk olarak, Java platformundaki sınıflar gibi başka bir kaynaktan gelen sınıfları kullandığınızda, erişim düzeyleri kendi sınıflarınızın hangi üyelerini kullanabileceğini belirler. İkincisi, bir sınıf yazarken, sınıfınızdaki her üye değişkenin ve her yöntemin hangi erişim düzeyine sahip olması gerektiğine karar vermeniz gerekir.


1
ek tam olarak nedir ve neden mevcut yayında bir düzenleme değildir?
15'te sehe

ek, Erişim Değiştiriciler'dir. Neden düzenleme yok? Kabul edilen cevabı tarihsel uğruna değiştirmeden tutmak ve cevabımı vermek.
ישו אוהב אותך

5

Kamu Korumalı Varsayılan ve özel erişim değiştiricilerdir.

Bunlar kapsülleme veya sınıfın içeriğini gizleme ve gösterme amaçlıdır.

  1. Sınıf herkese açık veya varsayılan olabilir
  2. Sınıf üyeleri herkese açık, korumalı, varsayılan veya özel olabilir.

Özel sınıf dışında erişilemiyor Varsayılan olarak yalnızca pakette erişilebilir. Paket içinde ve onu genişleten herhangi bir sınıfta korunur. Herkese açıktır.

Normalde, üye değişkenler özel olarak tanımlanır, ancak üye yöntemleri herkese açıktır.


Defaultbir erişim değiştiricisi değildir ve diğer ikisi yanlış yazılmıştır.
user207421

5

Çoğu zaman, herhangi bir dilin temel kavramlarını hatırlamanın gerçek dünya analojileri yaratarak mümkün olabileceğini fark ettim. Java'daki erişim değiştiricileri anlamak için benim benzetim:

Bir üniversitede öğrenci olduğunuzu ve hafta sonu sizi ziyarete gelen bir arkadaşınız olduğunu varsayalım. Kampüsün ortasında üniversitenin kurucusunun büyük bir heykeli olduğunu varsayalım.

  • Onu kampüse götürdüğünüzde, sizin ve arkadaşınızın ilk gördüğü şey bu heykel. Bu, kampüste yürüyen herkesin, üniversitenin izni olmadan heykele bakabileceği anlamına gelir. Bu heykeli KAMU yapar .

  • Sonra, arkadaşınızı yurtınıza götürmek istiyorsunuz, ancak bunun için onu bir ziyaretçi olarak kaydetmeniz gerekiyor. Bu, kampüsteki çeşitli binalara girmek için (sizinkiyle aynı) bir erişim geçişi aldığı anlamına gelir. Bu erişim kartını KORUNAN olarak yapar .

  • Arkadaşınız kampüs WiFi'ye giriş yapmak istiyor ancak bunu yapmak için herhangi bir kimlik bilgisi yok. Çevrimiçi olabilmesinin tek yolu, girişinizi onunla paylaşmanızdır. (Unutmayın, üniversiteye giden her öğrenci de bu giriş bilgilerine sahiptir). Bu, giriş bilgilerinizi NO MODIFIER olarak yapacaktır .

  • Son olarak, arkadaşınız web sitesinde yayınlanan dönem için ilerleme raporunuzu okumak istiyor. Ancak, her öğrencinin kampüs web sitesinin bu bölümüne erişmek için kendi kişisel girişi vardır. Bu, bu kimlik bilgilerini ÖZEL yapar .

Bu yardımcı olur umarım!


4

Eğer erişim değiştiricileri düşünüyorsun zaman sadece bu şekilde (her ikisi için de geçerlidir de düşünmek değişkenler ve yöntemlerle ):

public-> her yerden
privateerişilebilir -> sadece ilan edildiği sınıfta erişilebilir

Şimdi karışıklık söz konusu olduğunda ortaya çıkar defaultveprotected

default-> Erişim değiştirici anahtar sözcüğü yok. Bu kesinlikle sınıfın paketinde mevcut olduğu anlamına gelir. Bu paketin dışında hiçbir yere erişilemez.

protected-> defaultAynı paket sınıflarından biraz daha az katı bir şekilde, bildirildiği paketin dışındaki alt sınıflar tarafından erişilebilir .


4

Java erişimi, kullanabileceğiniz değişiklikleri değiştirir

resim açıklamasını buraya girin

Erişim değiştirici class, field[Hakkında] , için uygulanabilir method. Buna erişmeyi, alt sınıfı kullanmayı veya geçersiz kılmayı deneyin.

  • Erişim fieldveya methodbirclass .
  • Kalıtım. Ardıl class(alt sınıf) erişim değiştirici herhangi biri olabilir. Halef method(geçersiz kıl ) erişim değiştiricisi aynı olmalı veya genişletilmelidir

Üst seviye sınıf (birinci seviye kapsam) public vedefault . Nested class[Hakkında] bunlardan herhangi birine sahip olabilir

package paket hiyerarşisi için geçerli değil

Hızlı erişim değiştiricileri


2

Her şey kapsülleme ile ilgilidir (veya Joe Phillips'in belirttiği gibi, en az bilgi ).

En kısıtlayıcı (özel) ile başlayın ve daha sonra daha az kısıtlayıcı değiştiricilere ihtiyacınız olup olmadığını görün.

Hepimiz özel, genel, ... gibi yöntem ve üye değiştiricileri kullanıyoruz, ancak çok az geliştiricinin yaptığı bir şey, kodu mantıksal olarak düzenlemek için paketleri kullanmaktır .

Örneğin: Hassas güvenlik yöntemlerini bir 'güvenlik' paketine koyabilirsiniz. Ardından, bu paketteki güvenlikle ilgili bazı kodlara erişen ancak diğer güvenlik sınıfları paketini özel tutan bir ortak sınıf koyun . Bu nedenle, diğer geliştiriciler yalnızca halka açık olan sınıfı bu paketin dışından kullanabilirler (değiştiriciyi değiştirmedikçe). Bu bir güvenlik özelliği değildir, ancak kılavuz kullanımını.

Outside world -> Package (SecurityEntryClass ---> Package private classes)

Başka bir şey, birbirine çok bağlı olan sınıfların aynı pakette ortaya çıkabileceği ve bağımlılığın çok güçlü olması durumunda nihayetinde yeniden düzenlenebilir veya birleştirilebilir.

Aksine, her şeyi herkese açık olarak ayarlarsanız , neye erişilmesi gerektiği veya erişilmemesi gerektiği açık olmayacaktır, bu da çok fazla javadoc yazmaya yol açabilir (derleyici aracılığıyla hiçbir şey zorlamaz ...).


2

Özel korumalı-kamu-mükemmel-benzetme-için değişken veri tipleri

Blok diyagramıdır veri üyeleri açıklar sonra temel sınıf olan kalıtsal zaman türetilen sınıf erişim modu özel .

resim açıklamasını buraya girin

Not: Özel erişim belirtecine sahip veri üyelerini bildirmek, veri gizleme olarak bilinir .

Kaynak: Erişim Tanımlayıcıları - Özel, Genel ve Korumalı


1
Soru C ++ ile değil Java ile ilgiliydi.
Benoit

1
@Benoit Ama ne gönderdi, özel resimler, hem de aynı değildir: java ve c ++? Bu kurallar java için de geçerli değil? teşekkürler
leonidaa

2
C ++ 'da sadece 3 değiştirici varken java'da 4 vardır.
Benoit

1
benzetme iyidir, ancak varsayılan erişim belirteci eksik
mss

1
OP, "Java'da genel, korumalı, paket-özel ve özel arasındaki fark nedir?"
JL_SO

2

Benim görüşüm :)

özel:

class -> üst düzey bir sınıf özel olamaz. iç sınıflar aynı sınıftan erişilebilen özel olabilir.

örnek değişkeni -> yalnızca sınıfta erişilebilir. Sınıf dışında erişilemiyor.

paketlemek-özel:

class -> üst düzey bir sınıf pakete özel olabilir. Yalnızca aynı paketten erişilebilir. Alt paketten değil, dış paketten değil.

örnek değişkeni -> aynı paketten erişilebilir. Alt paketten değil, dış paketten değil.

korunmuş:

class -> üst düzey bir sınıf korunamaz.

örnek değişkeni -> Yalnızca aynı pakette veya alt pakette erişilebilir. Yalnızca sınıf genişletilirken paketin dışına erişilebilir.

halka açık:

class -> pakete / alt pakete / başka bir pakete erişilebilir

örnek değişkeni -> pakete / alt pakete / başka bir pakete erişilebilir

İşte detaylı cevap

https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md


1
  • halka açık

    Bir sınıf üyesi herkese açık olarak bildirilirse, ona herhangi bir yerden erişilebilir

  • korumalı

    Bir sınıf üyesi anahtar sözcük korumalı olarak bildirilirse, aynı sınıf üyelerinden, aynı paket içindeki sınıf üyelerinden ve devralınmış sınıf üyelerinden erişilebilir. Bir sınıf üyesi korunuyorsa, dış paket sınıfı miras alınmadıkça dış paket sınıfından erişilemez, yani diğer paket üst sınıfını genişletmez. Ancak korumalı bir sınıf üyesi her zaman aynı paket sınıfları için kullanılabilir.

  • varsayılan

    Java varsayılan olarak bir erişim değiştirici anahtar kelime DEĞİLDİR. Bir sınıf üyesi herhangi bir erişim değiştirici anahtar sözcüğü olmadan bildirilirse, bu durumda varsayılan üye olarak kabul edilir. Varsayılan sınıf üyesi her zaman aynı paket sınıfı üyeleri tarafından kullanılabilir. Ancak dış sınıflar korunan üyelerden farklı olarak alt sınıflar olsa bile dış paket sınıf üyesi varsayılan sınıf üyelerine erişemez

  • özel

    Bir sınıf üyesi anahtar kelime korumalı olarak bildirilirse, bu durumda SADECE aynı sınıf üyeleri tarafından kullanılabilir


-1

Java'da Erişim Belirtimleri: Java'da 4 erişim belirteci vardır; erişim sırasını artırmak için özel, paket-özel (varsayılan), korumalı ve genel.

Özel : Bir sınıf geliştirdiğinizde ve bu sınıfın bir üyesinin bu sınıfın dışında gösterilmemesini istediğinizde, bunu özel olarak bildirmeniz gerekir. özel üyelere yalnızca tanımlandıkları sınıfta erişilebilir, yani ek sınıf. özel üyelere 'bu' referansta ve ayrıca bu üyeleri kapsayan diğer sınıf örneklerinde, ancak bu sınıfın tanımında erişilebilir.

Özel paket (varsayılan) : Bu erişim belirteci, aşağıda açıklanan erişime ek olarak özel erişim belirteci tarafından belirtilen erişimi de sağlar.

Bir paket geliştirdiğinizde ve dolayısıyla bir sınıf (Sınıf1 diyelim) içinde, sınıf içindeki üyeyi (aynı) paketinizdeki diğer sınıflara göstermek için varsayılan (açıkça belirtilmesi gerekmez) erişim belirleyicisini kullanabilirsiniz. Bu diğer sınıflarda (aynı paket içinde), Class1 örneğinde bu varsayılan üyelere erişebilirsiniz. Ayrıca, bu varsayılan üyelere Class1'in alt sınıflarından, örneğin Class2'den (bu başvuruda veya Class1 örneğinde veya Class2 örneğinde) erişebilirsiniz.

Temel olarak, aynı paket içinde varsayılan üyelere doğrudan sınıf örneğinde veya alt sınıflardaki 'bu' referansta erişebilirsiniz.

korumalı : Bu erişim belirteci, aşağıda açıklanan erişime ek olarak paket-özel erişim belirteci tarafından belirtilen erişimi de sağlayacaktır.

Bir paket geliştirdiğinizde ve dolayısıyla bir sınıf (Sınıf1 diyelim) içinde, bu üyenin paketinizin dışına erişmesini istemiyorsanız, Sınıf1 içindeki veri üyesi için korumalı erişim belirteci kullanmanız gerekir. paketiniz, yani API'larınızı kullanan istemciniz), ancak bir istisna oluşturmak ve bu üyeye yalnızca istemci Class1'i genişleten Class2 sınıfını yazdığında bu üyeye erişim izni vermek istiyorsanız Bu nedenle, genel olarak, korunan üyelere türetilmiş sınıflardaki 'bu' referansla, yani Sınıf2'de ve ayrıca Sınıf2'nin açık örneklerinde erişilebilir olacaktır.

Lütfen aklınızda bulundurun:

  1. Class1'in açık bir örneğinde erişmeye çalışırsanız, Class2'deki Class1'in devralınmış korumalı üyesine erişemezsiniz.
  2. Class2'yi genişleten aynı / farklı paket içinde başka bir Class3 sınıfı yazdığınızda, Class1'den korunan üyeye bu başvuruda ve ayrıca Class3'ün açık örneğinde erişilebilir. Genişletilmiş olan herhangi bir hiyerarşi için bu geçerlidir, yani korumalı üyeye bu genişletilmiş sınıf başvurusunda veya örneğinde erişilebilecektir. Class3'te, Class2 örneğini oluşturursanız, korumalı üyeye, devralınmasına rağmen Class1'den erişemeyeceğinizi unutmayın.

Sonuç olarak, korumalı üyelere diğer paketlerden erişilebilir, ancak bu paketten bir sınıf bu korumalı üyeyi kapsayan sınıfı genişletir ve korumalı üyeye genişletilmiş sınıfın 'bu' referansı veya açık sınıf örneklerine erişilirse sınıf.

halka açık : Bu erişim belirteci, aşağıda açıklanan erişime ek olarak korumalı erişim belirteci tarafından belirtilen erişimi de sağlayacaktır.

Bir paket geliştirdiğinizde ve dolayısıyla bir sınıf (diyelim Class1) geliştirdiğinizde, bu üyenin başka bir sınıfta oluşturulan Class1 örneği gibi diğer paketlerde erişilebilir olmasını istiyorsanız, Class1 içindeki veri üyesi için genel erişim belirleyicisini kullanmalısınız. paketlemek. Temel olarak bu erişim belirteci, veri üyenizi herhangi bir koşul olmadan dünyaya tanıtmak istediğinizde kullanılmalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.