2013-04-03 7 views
12

पर सबक्लास के लिए संरक्षित पहुंच प्रतिबंध मुझे पता है कि इस मंच में इससे पहले पूछा गया है लेकिन मैं फिर से पूछूंगा क्योंकि मुझे कोई अच्छा जवाब नहीं दिख रहा है (अब तक)।जावा: सुपरक्लास ऑब्जेक्ट

यहाँ यह जाता है:

package a; 
public class A{ 
    protected int a; 
} 

package b; 
public class B extends A{ 
} 

package c; 
public class C extends B{ 
    public void accessField(){ 
     A ancient = new A(); 
     ancient.a = 2; //A - That wouldn't work. 

     a = 2; //B - That works. 
    } 

} 

क्यों खंड ए) काम नहीं करेगा? उपclass सी में superclass वस्तु प्राचीन पहुंच पर इस प्रतिबंध के पीछे तर्कसंगत क्या है?
धन्यवाद।

+1

मुझे लगता है कि मामले को चित्रित करने के लिए यहां एक विरासत चरण अनावश्यक है। – Vitaly

+2

@ होवरक्राफ्टफुलऑफेल मुझे लगता है कि सवाल व्यावहारिक से अधिक सैद्धांतिक है लेकिन अनिच्छुक नहीं है। – assylias

उत्तर

6

संरक्षित सदस्यों को केवल उसी पैकेज के बाहर एक्सेस किया जा सकता है यदि यह विरासत के माध्यम से है - यानी पदानुक्रम के भीतर।

तो जब आप एक अलग पैकेज से ए का एक और उदाहरण बना रहे हैं, तो यह विरासत संबंध नहीं है और यह इस प्रकार विफल रहता है।

हमेशा की तरह, इस JLS में कवर किया जाता है, 6.6.2:

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

+0

मैं उलझन में हूँ। वही खंड यह भी कहता है "* एक्सेस केवल सी के उप-वर्ग एस के शरीर के भीतर ही अनुमति है * - यह * प्रत्यक्ष * सबक्लास नहीं कहता है, केवल उपclass ... – assylias

+0

@assylias मेला बिंदु - यह मेरा मतलब नहीं है इस उदाहरण में सीधे, लेकिन मैं देखता हूं कि यह कैसे संदिग्ध हो सकता है इसलिए मैंने थोड़ा सा शब्द बदल दिया है! – berry120

+1

@ berry120 धन्यवाद! – yapkm01

1

पुस्तक प्रोग्रामिंग भाषा 3 संस्करण से उद्धरण। गोसलिंग एट सभी द्वारा - पेज 81 सेकंड 3,5

"क्या संरक्षित वास्तव में इसका मतलब है" - .. वर्ग ही है और एक ही पैकेज में कोड करने के भीतर सुलभ होने के बजाए, एक संरक्षित सदस्य भी माध्यम से एक वर्ग से पहुँचा जा सकता ऑब्जेक्ट संदर्भ जो हैं, कम से कम उसी प्रकार के वर्ग के रूप में - यह वर्ग के प्रकार या उसके उप-वर्ग

5

वास्तव में आपको विरासत के दो स्तरों की आवश्यकता नहीं है और नीचे दिए गए कोड से वही व्यवहार होगा :

public class B extends A{ 
    public void accessField() { 
     A ancient = new A(); 
     ancient.a = 2; //A - That wouldn't work. 

     a = 2; //B - That works. 
    } 
} 

कारण है कि a = 2 काम करता है JLS 6.2.2.1 है:

Let वर्ग है, जिसमें एक संरक्षित सदस्य घोषित किया जाता है हो सकता है सी। प्रवेश केवल सी का एक उपवर्ग एस

ध्यान दें कि यह नहीं कहता है प्रत्यक्ष उपवर्ग, लेकिन केवल उपवर्ग के शरीर के भीतर की अनुमति है। तो a = 2B कक्षा या C कक्षा के भीतर काम करता है।

पहुँच एक योग्य नाम Q.Id, जहां क्यू एक ExpressionName है के द्वारा होता है, तो पहुँच है:

दूसरी ओर, ancient.a = 2; एक ही खंड में अगले बुलेट बिंदु से आच्छादित है यदि ancient के प्रकार B या का एक उपवर्ग था की अनुमति दी यदि और केवल यदि अभिव्यक्ति क्यू के प्रकार एस या एस

आपके मामले में की एक उपवर्ग है, Q.Idancient.a है => यह केवल सुलभ हो जाएगा B।उदाहरण के लिए तो, यह संकलन होगा:

public class B extends A{ 
    public void accessField() { 
     C ancient = new C(); 
     ancient.a = 2; //A - That wouldn't work. 
    } 
} 
0

से JLS 6.6.2

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

जब आप कहते हैं,

A ancient = new A(); 
ancient.a = 2; 

आप प्राचीन (ए वस्तु) से कुछ भी नहीं है और इस तरह इसके कार्यान्वयन के लिए जिम्मेदार इनहेरिट नहीं कर रहे हैं। सी बनाकर बढ़ाता है, तो आप पहले से ही एक अलग ऑब्जेक्ट से 'ए' प्राप्त कर चुके हैं, इसलिए नीचे दिया गया कथन काम करता है।

a = 2; 

हैं, तो

ancient.a = 2; 

काम करता है, तो एक सार्वजनिक और निजी पहुँच विनिर्देशक के बीच अंतर नहीं है।

संबंधित मुद्दे