2015-11-19 11 views
31

मुझे समझ में क्यों वर्ग के सदस्यों की पहुंच के बीच एक अंतर है जब कंस्ट्रक्टर्स के बारे में बोलकर देखें।जावा निजी कंस्ट्रक्टर्स दृश्यता

निम्न उदाहरण पर विचार करें:

class A { 
    static class B { 
    private B(String s) {} 
    private void foo() {} 
    } 
    static class C extends B { 
    public C(String s) { 
     super(s); // call B(String), which is private, and obviously accessible 
    } 
    void bar() { 
     foo(); // compilation error (symbol unknown), as B.foo() is private 
    } 
    } 
} 

A की निजी सदस्यों, निजी होने के रूप में, B से सुलभ नहीं होना चाहिए। खेतों और तरीकों के लिए, यह मामला है, लेकिन यह है कि निर्माताओं के एक ही नियम का पालन नहीं कर रहे हैं लगता है।

JLS-8 (6.6.1. Determining Accessibility) से, हम पढ़ सकते हैं:

[...]

एक सदस्य एक संदर्भ प्रकार के (वर्ग, इंटरफ़ेस, क्षेत्र, या विधि), या एक वर्ग के प्रकार के एक निर्माता, पहुँचा जा सकता है केवल तभी प्रकार पहुँचा जा सकता है और सदस्य या निर्माता का उपयोग की अनुमति के लिए घोषित किया जाता है:

  • [...]

  • ,210
  • अन्यथा, सदस्य या निर्माता private घोषित किया जाता है, और यदि और केवल यदि यह शीर्ष स्तर वर्ग के शरीर के भीतर होता है (§7.6) कि सदस्य या निर्माता की घोषणा encloses पहुँच अनुमति दी है।

किसी को भी मुझे बता सकते हैं क्यों निर्माता C से पहुँचा जा सकता है, यहां तक ​​कि घोषित किया गया private जबकि?

+1

सिर्फ इसलिए कि आप सुपर कॉल कर सकते हैं इसका मतलब यह नहीं है कि कन्स्ट्रक्टर पहुंच योग्य है – michaelsnowden

+2

क्या कोई मुझे बता सकता है कि कन्स्ट्रक्टर सी से क्यों पहुंचा जा सकता है, भले ही निजी घोषित किया जा सके? -> क्योंकि बी और सी दोनों आंतरिक कक्षाएं हैं। यदि आप बी और सी को ए –

+3

@ जोर्नबुइटिंक के बाहर ले जाते हैं तो अब और काम नहीं करेंगे: यदि ऐसा है, तो 'foo()' * * * क्यों उपलब्ध नहीं है? यहां एक असंगतता प्रतीत होती है। –

उत्तर

25

विधि foo() निजी है, इसलिए आप इसका वारिस नहीं करते हैं और इसे C कक्षा से सीधे कॉल नहीं कर सकते हैं।

हालांकि, अगर आप B से निजी तरीकों और निर्माता को देखने के बाद से सब कुछ एक ही युक्त वर्ग में घोषित किया जाता है, और यही वजह है कि super() काम करता है super साथ उन तक पहुँचने, कर सकते हैं। उसी तरह, आप super.foo() साथ foo पहुँच सकते हैं।

ध्यान दें कि आप C में एक नई foo विधि को फिर से परिभाषित कर सकते हैं, लेकिन यह विधि B.foo() को ओवरराइड नहीं करेगी।

आप foo उपयोग नहीं कर सकते, क्योंकि यह तो तुम सी में यह वारिस नहीं है

हालांकि निजी घोषित किया जाता है, के रूप में टिप्पणी में नोट किया गया था आप उपयोग कर सकते हैं:

+0

धन्यवाद आपके उत्तर WilQu & @benzonico के लिए बहुत कुछ। यह चाल है। मैं इसके परिणामस्वरूप आपका जवाब स्वीकार करता हूं। –

3

तो चाल यहाँ निम्नलिखित हो सकता है super.foo(); क्योंकि super एक प्रकार है कि एक ही शीर्ष स्तर वर्ग में घोषित किया जाता है को संदर्भित करता है (इस के लिए JLS 6.6.1 देखें)।

फिर चाल कि super.<init>(s) जो के रूप में super.foo()

-2

फू() विधि foo के रूप में, वर्ग सी में सुलभ नहीं है() विधि निजी और निजी है इसी मामले जा रहा समाप्त होता है बुला के रूप में super(s) बुला देखी जा सकती है है विधि आधार वर्ग को विरासत में मिला नहीं किया जा सकता।

रचनाकारों के लिए, कभी भी संरक्षक कभी भी शामिल नहीं होते हैं। इसके अलावा, मैं इस कोड को संकलित:

class Vehicle{ 
     int speed=50; 
     private Vehicle() 
     { 
      System.out.println("Private Vehicle constructor"); 
     } 
    } 
    public class Bike4 extends Vehicle{ 
     int speed=100; 
    Bike4() 
    { 
     super(); 
     System.out.println("Hi I n constructor"); 
    } 
    void display(){ 
    System.out.println(super.speed);//will print speed of Vehicle now 
    } 
    public static void main(String args[]){ 
    Bike4 b=new Bike4(); 
    b.display(); 

} 
} 

और संकलित समय त्रुटि मिलती है:)() वाहन (वाहन सुपर में निजी पहुँच गया है; ^ जो स्पष्ट रूप से इंगित करता है कि एक निजी निर्माता को सुपर का उपयोग करके एक्सेस नहीं किया जा सकता है। यदि हम एक निजी कन्स्ट्रक्टर को प्रारंभ या एक्सेस करने में सक्षम हैं, तो निजी कन्स्ट्रक्टर बनाने में क्या बात है।

+0

कृपया अन्य उत्तरों देखें, आपका प्रश्न वास्तव में प्रासंगिक नहीं है। – benzonico

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