2013-08-28 7 views
22

मैंने सुरक्षित और पैकेज निजी संशोधक के बीच मतभेदों पर विभिन्न लेख देखे हैं। एक बात मैं इन दो पदोंअंतर?

  1. Isn't "package private" member access synonymous with the default (no-modifier) access?

    इस में के बीच विरोधाभासी पाया स्वीकार किए जाते हैं जवाब कहते हैं

    संरक्षित संशोधक निर्दिष्ट करता है कि कि सदस्य केवल अपने स्वयं के पैकेज में पहुँचा जा सकता है (पैकेज-प्राइवेट के साथ) और, इसके अलावा, किसी अन्य पैकेज में अपनी कक्षा के उप-वर्ग द्वारा।

  2. Why the protected modifier behave differently here in Java subclass?

    यह स्वीकार जवाब में कहा गया है कि

    संरक्षित स्तर तक पहुँच संतुष्ट करने के लिए दो शर्तें पूरी होनी चाहिए:

    • कक्षाएं एक ही पैकेज में होना चाहिए ।
    • एक विरासत संबंध होना चाहिए।

वे विरोधाभासी नहीं हैं? अन्य लेखों की मेरी समझ से, पहली पोस्ट सही उत्तर देता है जो अन्य पैकेज में == पैकेज-निजी + सबक्लास सुरक्षित है।

यदि यह कथन सही है, तो क्यों इस कोड को मेरी उपवर्ग बिल्ली पर निम्न त्रुटि संदेश के साथ लाइन 17

The method testInstanceMethod() from the type Animal is not visible 

सुपर और उपवर्ग के लिए मेरे कोड से नीचे हैं पर विफल रहता है।

package inheritance; 

public class Animal { 

    public static void testClassMethod() { 
     System.out.println("The class" + " method in Animal."); 
    } 
    protected void testInstanceMethod() { 
     System.out.println("The instance " + " method in Animal."); 
    } 
} 

package testpackage; 

import inheritance.Animal; 

public class Cat extends Animal{ 
     public static void testClassMethod() { 
      System.out.println("The class method" + " in Cat."); 
     } 
     public void testInstanceMethod() { 
      System.out.println("The instance method" + " in Cat."); 
     } 

     public static void main(String[] args) { 
      Cat myCat = new Cat(); 
      Animal myAnimal = myCat; 
      myAnimal.testClassMethod(); 
      myAnimal.testInstanceMethod(); 
     } 
    } 

कृपया स्पष्ट करें कि उपर्युक्त कोड विफल क्यों होता है। यह बहुत उपयोगी होगा। धन्यवाद

+1

testInstanceMethod() का उपयोग करने के लिए आपको बिल्ली होना है। पशु को कास्टिंग पैकेज विधि में उस विधि तक पहुंच प्रतिबंधित करता है और चूंकि आपका मुख्य पैकेज अलग-अलग पैकेज में है, इसलिए कोड विफल हो जाता है। (मुझे लगता है कि यह संकलन भी नहीं करेगा)। हां विधि है लेकिन आपको इसे एक्सेस करने की अनुमति नहीं है क्योंकि इसे संरक्षित द्वारा पशु में घोषित किया गया है। – PSIXO

+0

दूसरा कथन इस प्रकार तैयार किया जाना चाहिए था: * "संरक्षित स्तर की पहुंच को पूरा करने के लिए, ** ** दो स्थितियों में से एक को पूरा किया जाना चाहिए ..." * (उस उत्तर के नीचे मैंने जो टिप्पणी भी बनाई है उसे भी देखें।) – aioobe

उत्तर

21

पहले उत्तर मूल रूप से सही है - protected सदस्यों अन्य संकुल

हालांकि से एक ही पैकेज से

  • वर्गों द्वारा पहुँचा जा सकता है की घोषणा वर्ग के
  • उपवर्गों, वहाँ है एक छोटी सी चाल:

    6.6.2 संरक्षित एक्सेस

    किसी ऑब्जेक्ट का एक संरक्षित सदस्य या कन्स्ट्रक्टर पैकेज के बाहर से एक्सेस किया जा सकता है जिसमें इसे केवल उस कोड द्वारा घोषित किया जाता है जो उस ऑब्जेक्ट के कार्यान्वयन के लिए ज़िम्मेदार है।

    इसका मतलब है कि अन्य पैकेज से उपवर्ग उनके सुपर-क्लास की मनमानी उदाहरणों में से protected सदस्यों उपयोग नहीं कर सकते, वे केवल (अपने स्वयं के प्रकार के मामलों में जहां प्रकार अभिव्यक्ति की एक संकलन समय प्रकार है पर उन तक पहुँच सकते, क्योंकि यह एक है संकलन समय जांच)।

    उदाहरण के लिए (यह मानते हुए कि इस कोड Cat में है):

    Dog dog = new Dog(); 
    Animal cat = new Cat(); 
    
    dog.testInstanceMethod(); // Not allowed, because Cat should not be able to access protected members of Dog 
    cat.testInstanceMethod(); // Not allowed, because compiler doesn't know that runtime type of cat is Cat 
    
    ((Cat) cat).testInstanceMethod(); // Allowed 
    

    यह समझ में आता है, क्योंकि Cat द्वारा Dog की protected सदस्यों में से पहुँचने के Dog की अपरिवर्तनशीलताओं टूट सकती है, जबकि Cat अपनी ही protected सदस्यों तक पहुँच सकते हैं सुरक्षित रूप से, क्योंकि यह जानता है कि अपने स्वयं के आविष्कारों को कैसे सुनिश्चित किया जाए।

    विस्तृत नियम:

    6.6.2.1 एक संरक्षित सदस्य तक पहुंच

    Let सी क्लास, जिसमें एक संरक्षित सदस्य मीटर घोषित किया जाता है हो सकता है। प्रवेश केवल सी का एक उपवर्ग एस इसके अलावा के शरीर के भीतर की अनुमति दी है, ईद एक दृष्टांत फ़ील्ड या उदाहरण विधि है, तो अर्थ है यदि:

    • पहुँच एक योग्य नाम Q.Id, जहां क्यू है द्वारा है एक अभिव्यक्ति नाम, तब पहुंच की अनुमति है यदि केवल अभिव्यक्ति क्यू का प्रकार एस है या एस
    • का उप-वर्ग यदि पहुंच फ़ील्ड एक्सेस अभिव्यक्ति ई.आईडी द्वारा है, जहां ई प्राथमिक अभिव्यक्ति है, या एक विधि आमंत्रण अभिव्यक्ति ई.आईडी (...।) द्वारा, जहां ई प्राथमिक अभिव्यक्ति है, तब पहुंच की अनुमति है यदि केवल ई का प्रकार एस है या एस

    का उप-वर्ग 6.6.2.2 एक संरक्षित निर्माता

    Let सेल्सियस के लिए योग्य पहुँच वर्ग है, जिसमें एक संरक्षित निर्माता घोषित किया जाता है हो सकता है और एस में अंतरतम वर्ग जिसका घोषणा संरक्षित निर्माता के उपयोग होता हो। तब:

    • पहुँच एक सुपर क्लास निर्माता मंगलाचरण सुपर द्वारा है या रूप E.super के एक योग्य सुपर क्लास निर्माता मंगलाचरण से है, जहां ई एक प्राथमिक अभिव्यक्ति है, तो (।।।) (।।।) पहुंच की अनुमति है।
    • यदि पहुंच किसी अज्ञात वर्ग के उदाहरण के रूप में नई सी (।।।) {...} के रूप में निर्माण अभिव्यक्ति अभिव्यक्ति है या किसी योग्य वर्ग उदाहरण के रूप में फॉर्म E.new C (।।।) { ...}, जहां ई प्राथमिक अभिव्यक्ति है, तो पहुंच की अनुमति है।
    • अन्यथा, यदि पहुंच एक साधारण वर्ग उदाहरण के रूप में नई सी (...।) के रूप में निर्माण अभिव्यक्ति अभिव्यक्ति अभिव्यक्ति या किसी योग्य वर्ग उदाहरण द्वारा ई.न्यू सी (।।) के रूप में अभिव्यक्ति अभिव्यक्ति द्वारा बनाई गई है, जहां ई है एक प्राथमिक अभिव्यक्ति, तब पहुंच की अनुमति नहीं है। एक संरक्षित कन्स्ट्रक्टर को क्लास इंस्टेंस सृजन अभिव्यक्ति (जिसे अज्ञात वर्ग घोषित नहीं किया जाता है) द्वारा केवल उस पैकेज के भीतर से पहुंचा जा सकता है जिसमें इसे परिभाषित किया गया है।

    यह भी देखें:

+0

मुझे लगता है कि मैं समझा, लेकिन अभी भी पचाने और इसे पाने के लिए कुछ समय चाहिए। जब ओवरराइडिंग करते हैं, तो क्या हमें एक्सेस संशोधक के साथ विधि हस्ताक्षर को बनाए रखना होगा? ऐसा प्रतीत होता है कि, अगर एक सुपरक्लास ने शून्य() {} 'को सुरक्षित किया है और एक उप-वर्ग जो ओवरराइड करता है, तो उसे 'शून्य प्राप्त नहीं हो सकता है) {}' , यानी डिफ़ॉल्ट पहुंच। लेकिन इसमें 'सार्वजनिक शून्य प्राप्त हो सकता है() {} 'या' संरक्षित शून्य प्राप्त() {} ' – eagertoLearn

+2

@eagertoLearn - इसके पीछे का विचार एक उप-वर्ग हमेशा विधियों को अधिक सुलभ बना सकता है लेकिन कम पहुंच योग्य नहीं हो सकता है; इस तरह, सबक्लास अभी भी सुपर-क्लास अनुबंध के अनुरूप है। यह कहकर कि एक और तरीका, सुपर-क्लास को कास्टिंग करना आपको कभी भी अधिक तरीकों तक पहुंच नहीं देना चाहिए। –

0

तुम एक बिल्ली उदाहरण बनाया और उसके सुपर वर्ग प्रकार अर्थात पशु प्रकार में डाली है। पशु प्रकार के अनुसार इसका testInstanceMethod एक ही पैकेज या किसी उपप्रकार में दिखाई देता है। यदि आपने पशु प्रकार में नहीं डाला तो कोड संकलित होगा।

आशा है कि

./Arun

1

में मदद करता है सुरक्षित पहुँच सदस्यों को एक ही पैकेज में पहुंचा जा सकता है और के लिए एक और पैकेज में विरासत में मिला वर्ग के सदस्य भी पहुँचा जा सकता है।

पैकेज में एक्सेस में उसी पैकेज में कक्षाओं के सदस्यों तक पहुंच प्राप्त की जा सकती है। अन्य पैकेजों में कक्षा के सदस्यों को पैकेज एक्सेस में एक्सेस नहीं किया जा सकता है।

+2

यह प्रश्न पहले से ही एक स्वीकृत उत्तर के साथ तीन साल से अधिक पुराना है। आपका उत्तर पहले से ही स्वीकृत उत्तर के लिए कुछ भी सार्थक नहीं जोड़ता है, इसलिए मुझे वास्तव में आपके उत्तर में कोई बिंदु नहीं दिख रहा है (कोई अपराध नहीं)। – rayryeng

+1

"स्वीकृत उत्तर" को पढ़कर मेरी आंखें खून बह गईं ... मैं एक भाषा वाक्यविन्यास वकील नहीं हूं (और टीवी पर एक नहीं खेलता) इसलिए मैं वास्तव में इस "अधिक संक्षिप्त" उत्तर की सराहना करता हूं। – geowar