2010-08-19 15 views
14

में संरक्षित डेटा में मेरे प्रश्न में विशेष रूप से जावा, सार कक्षाएं और संरक्षित डेटा का उपयोग शामिल है। मुझे बताया जा रहा है कि सभी डेटा निजी होना चाहिए, और संरक्षित गेटर्स/सेटर्स केवल इस्तेमाल किए जाने चाहिए।अमूर्त वर्ग

अब, मैं समझता हूं कि हम कक्षा के आकस्मिक उपयोगकर्ताओं द्वारा प्रत्यक्ष हेरफेर से डेटा को ढालना चाहते हैं, और आम तौर पर सार्वजनिक डेटा सदस्य एक संदिग्ध अभ्यास हैं। मैं "जावा संरक्षित क्षेत्रों बनाम सार्वजनिक टिककर खेल" (Java protected fields vs public getters) पर ध्यान दिया है, लेकिन मैं अभी भी संदिग्ध है कि हूँ:

protected int i; 

से एक अमूर्त वर्ग में भी बदतर है:

private int i; 
protected int geti(); 
protected void seti(int j); 

मैं कर रहा हूँ बस नहीं देख नीचे की ओर जब अमूर्त वर्ग बच्चों के वर्गों के लिए माता-पिता/सामान्य सुविधा प्रदान करने के लिए ठीक है, और संरक्षित दायरा बच्चों के लिए पहुंच प्रदान करने के लिए है, जबकि आकस्मिक उपयोगकर्ताओं से डेटा की सुरक्षा करते हैं। मैं ऊपर उल्लिखित प्रश्न में नोट करता हूं कि अधिकांश उत्तर इस मुद्दे को संबोधित करते हैं कि आम तौर पर डेटा सार्वजनिक रूप से क्यों निजी होना चाहिए। मैं विशेष रूप से बच्चों द्वारा उपयोग के लिए एक अमूर्त माता-पिता में मौजूद डेटा पर अपने प्रश्न पर ध्यान केंद्रित करने की कोशिश कर रहा हूं। एकमात्र उचित टिप्पणी मैंने आज तक सुना है कि माता-पिता संरक्षित डेटा (उदाहरण के लिए, ऊपर मैं int) का उपयोग करके आपको बच्चे वर्ग में कोड के साथ छोड़ देता है जो बाल वर्ग में घोषित एक चर का संदर्भ देता है। कम आकर्षक तर्क है (Common protected data member in base class? देखें) कि आप कुछ दिन तक पहुंच बदलना चाहते हैं, और अब आपको अपने इंटरफेस का सम्मान करना होगा। यह एक अमूर्त वर्ग है, और इसका उद्देश्य 100% समय तक बढ़ाया जाना है।

धन्यवाद! पुस्तकों के लिए विशिष्ट शीर्षक/पेज # संदर्भ में कहीं अधिक सहायक होते हैं कि संदर्भ के लिए "..any बुनियादी जावा प्रोग्रामिंग पाठ ..."

=================== ======================= 10-13-2010
यह सार वर्गों के बारे में एक सवाल था क्योंकि यह संरक्षित डेटा के बारे में है। मुझे यह निराशाजनक लगता है कि ओओपी (डेटा: हाँ) में डेटा छिपाना एक अच्छी बात है या नहीं, इस पर प्रतिक्रिया में बदलाव आया है। अमूर्त वर्ग की प्रकृति को शामिल करने में बहुत गहराई है, और यह नियमित गैर-अंतिम वर्ग से अलग कैसे है, और उपयोग के लिए अमूर्त माता-पिता में डेटा-आइटमों के नामों और प्रकारों को ठीक करने के लिए क्या संभव फायदे हो सकते हैं बाल वर्ग मुझे लगता है कि यहां नवाचार के लिए संभावना है और अमूर्त माता-पिता से कार्यान्वित बाल वर्गों तक अधिक नियंत्रण बढ़ाया जा रहा है। मुझे चिंतित है कि सामान्य सिद्धांत, जैसे डेटा-छिपाने के फायदे, सिद्धांत बन सकते हैं, और नवाचार को रोक सकते हैं और नए पैटर्न और विचारों के विकास को रोक सकते हैं।

योगदान देने वाले सभी लोगों के लिए धन्यवाद।

+0

[मैं सिर्फ कहीं और इस जवाब दे दिया।] (Http://stackoverflow.com/questions/3525405/sometimes-i-dont-get-why-we-go-so-far-as-to-make-every- सिंगल-फील्ड-ए-प्राइवेट-ए/3525629 # 3525629) – cHao

+1

दरअसल, श्री हाओ, आपने एक अलग प्रश्न का उत्तर दिया। सार्वजनिक और निजी की सामान्य चर्चा यहां सवाल नहीं है, जब तक कि आप यह मानते हैं कि विरासत एक प्रकार का इंटरफ़ेस नहीं है? – cvsdave

उत्तर

11

यदि फ़ील्ड निजी है और पहुंच गेटर्स और सेटर्स के माध्यम से है, तो आप गेटर्स और सेटर्स को पुन: कार्यान्वित करने में सक्षम होंगे (उदाहरण के लिए, फ़ील्ड छोड़ना और बाहरी स्रोत से मूल्य को अपडेट करना/पढ़ना), और इस प्रकार बदलते हैं कि कैसे "फ़ील्ड" किसी भी बच्चे वर्ग को छूए बिना काम करता है।

चाहे यह इसके लायक है, यह आपके ऊपर है।

+1

यह तर्क # 2 है, प्रश्न – cvsdave

+2

प्रश्न में वर्णित "कम मजबूती" ठीक है, अन्य उत्तरों में उल्लिखित कुछ मामूली पैकेज दृश्यता विवरण के अलावा, मेरा मानना ​​है कि संरक्षित गेटर्स और सेटर्स के साथ एक क्षेत्र निजी बनाने के लिए यह एकमात्र तर्क है। व्यक्तिगत रूप से, मुझे नहीं लगता कि यह बहुत ही आकर्षक है ... जावा में गेटर्स और सेटर्स परेशान हैं। – alex

9

उपवर्गों के लिए एक इंटरफ़ेस के रूप में संरक्षित तरीकों, उसी तरह से की लगता है कि सार्वजनिक तरीकों हर किसी के लिए एक इंटरफेस है।

एक्सेसर्स प्रदान करना बेस क्लास को अपने राज्य को बनाए रखने में सक्षम बनाता है: कोई भी रास्ता नहीं है कि उप-वर्ग किसी जानबूझकर चाल के बिना भ्रष्ट हो जाए।

+2

मूल वर्ग, सार होने के नाते, कोई राज्य नहीं हो सकता है, क्योंकि इसे लागू नहीं किया जा सकता है। मुझे लगता है कि यह मेरे तर्क का हिस्सा है; एसडीएएम के फैसले एक अमूर्त माता-पिता को एक ठोस माता-पिता के रूप में लागू नहीं होते हैं। इस संदर्भ में, मुझे लगता है कि इंटरफेस के विचार को पेश करने से शायद इस सवाल से परेशान हो जाता है, हालांकि यह एक दिलचस्प विचार है। आपके कमेंट के लिए धन्यवाद। – cvsdave

+0

@cvsdave: आधार वर्ग स्पष्ट रूप से * हो सकता है * राज्य हो सकता है, या इसके बारे में सवाल पूछने का कोई कारण नहीं होगा कि क्यों और क्यों (या क्यों नहीं) इसका खुलासा किया जाए। और भी, बेस क्लास में संभावित रूप से ऐसे क्षेत्र हैं जो उस क्षेत्र पर भरोसा करते हैं, और इस प्रकार इसकी वैधता पर निर्भर करते हैं। (यदि ऐसा नहीं होता है, तो फ़ील्ड बेस क्लास में बिल्कुल संबंधित नहीं है, और केवल गेटर और सेटर घोषित किया जाना चाहिए - बेशक, अमूर्त,) – cHao

1

यदि आपको अपने बच्चे को पर सीधे तक पहुंचने की आवश्यकता नहीं है, तो आप उन्हें क्यों देंगे?

यह सुरक्षित उपयोग करने के लिए नीचे की ओर नहीं है। लेकिन यदि यह आवश्यक नहीं है, तो शायद इससे बचें और अपने क्षेत्रों पर पहुंच नियंत्रित करें।

0

यदि कोई आपकी कक्षा को उप-वर्ग बनाता है, और उप-वर्ग को आपके वर्तमान वर्ग के समान पैकेज में रखता है, तो वे आपके गेटर्स और सेटर्स को ओवरराइड करना चाहेंगे। उदाहरण के लिए, वे यह सुनिश्चित करना चाहते हैं कि i केवल 1.

से अधिक मान पर सेट हो सकता है, इसके अलावा, यह वास्तव में आपके ऊपर है। सम्मेलन यह है कि हालांकि सब कुछ के लिए गेटर्स और सेटर्स हैं।

+0

यह तर्क # 2 है, "कम आकर्षक" सवाल में कहा गया है। – cvsdave

+0

हम्म, मैं नहीं देखता कि मुझे कैसे याद आया कि यह वहां था। क्या बाद में संपादित किया गया था? – Serplat

1

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

साथ ही यह मुद्दा है कि एलेक्स पहले उठाया गया था।

0

विरासत से संबंधित कक्षाओं में भी जानकारी छुपा मूल्यवान है।

के रूप में ऊपर एलेक्स द्वारा उल्लेख किया, फिर से कार्यान्वयन प्रदान करने के अलावा:

  • आप तरीकों में breakpoints सेट कर सकते हैं।
  • आप एक ही स्थान पर बाधा डाल सकते हैं।
3

कम पहुंच होने से कोई कमी नहीं होती है, यह एक लाभ है। कक्षाओं को हमेशा जितना संभव हो उतना आंतरिक राज्य तक पहुंच सीमित करनी चाहिए। इस बारे में मत सोचो कि आंतरिक क्यों छिपे रहना चाहिए, इसके बजाय सोचें कि उन्हें क्यों उजागर किया जाना चाहिए। इस मामले में हर मामले में, जब तक वेरिएबल का पर्दाफाश करने का वास्तव में कोई अच्छा कारण न हो तो उसे बेनकाब न करें।

+1

यह सार वर्गों और संरक्षित के संबंध में विशिष्ट मुद्दे पर कैसे लागू होता है? "... उन्हें क्यों उजागर किया जाना चाहिए ..." यही कारण है कि वैकल्पिक मामले में सेटर/गेटर लिखा गया है। अगर पहुंच की आवश्यकता नहीं थी, तो सवाल लागू नहीं होगा! – cvsdave

+1

फ़ील्ड को सुरक्षित के रूप में बेनकाब न करें। इसे निजी बनाएं और यदि आवश्यक हो तो गेटर और/या सेटर का उपयोग करें। यह जितना संभव हो सके पहुंच को सीमित करता है, जो हमेशा अच्छा होता है। –

0

आप क्योंकि protected int i; उपयोग द्वारा (जिसमें हर कीमत पर से बचना चाहते हैं) क्षेत्र अधिभावी के लिए अनुमति देता getters/setters उपयोग करना चाहते हैं।

आप फील्ड ओवरराइडिंग को अस्वीकार करना चाहते हैं क्योंकि यह विधि ओवरराइडिंग से अलग तरीके से काम करता है। फ़ील्ड ओवरराइडिंग ओवरराइड फ़ील्ड को पहुंच योग्य नहीं बनाता है (संदर्भ का प्रकार निर्धारित करता है कि आप किस क्षेत्र के साथ काम कर रहे हैं)।

पहुंच योग्य फ़ील्ड अंतिम या कक्षा में अंतिम होना चाहिए।

public class OverridingFun { 
    public static class Base { 
     public int i = 1; 
     public int getI(){ return i; } 
    } 
    public static class A extends Base { 
     public int i = 2; 
     public int getI(){ return i; } 
    } 
    public static class B extends A { 
     public int i = 3; 
     public int getI(){ return i; } 
    } 
    public static void main(String [] args){ 
     B b = new B(); 
     A bAsA = b; 
     Base bAsBase = b; 

     System.out.println(b.getI());//3 
     System.out.println(bAsA.getI());//3 
     System.out.println(bAsBase.getI());//3 

     System.out.println(b.i);//3 
     System.out.println(bAsA.i);//2 
     System.out.println(bAsBase.i);//1 

     b.i = 4; 
     bAsA.i = 5; 
     bAsBase.i = 6; 

     System.out.println(b.i);//4 
     System.out.println(bAsA.i);//5 
     System.out.println(bAsBase.i);//6 
    } 
} 

पहली नज़र में यह कुछ ऐसा है बस कोड को पढ़ने के लिए मुश्किल है, लेकिन यह कार्यक्षमता पर प्रभाव पड़ता है बनाना होगा की तरह दिखता है। मान लें कि फ़ील्ड को व्युत्पन्न वर्ग द्वारा ओवरराइड किया जाता है, क्योंकि सेटर्स का उपयोग नहीं किया जा रहा है, बेस फ़ील्ड को स्वचालित रूप से अपडेट करने का कोई तरीका नहीं है और यह पता लगाने का कोई तरीका नहीं है कि किसी ने बेस फ़ील्ड बदल दिया है (क्योंकि बेस मान अभी भी सुलभ है) व्युत्पन्न क्षेत्र को अद्यतन करें। यह कल्पना करना आसान है कि आधार और व्युत्पन्न राज्य सिंक से बाहर हो सकते हैं और त्रुटियों को ट्रैक करना मुश्किल होगा। बस इसे एक बहुत भंगुर एपीआई के लिए बनाता है।

दुर्भाग्य से final कीवर्ड के बाद से इसकी रक्षा करने का कोई तरीका नहीं है, जो ओवरराइडिंग के खिलाफ सुरक्षा करता है, एक बार फ़ील्ड लिखने के लिए भी बनाता है। तो कोई लिखने योग्य गैर अधिभार योग्य फ़ील्ड।

व्यक्तिगत रूप से मुझे आश्चर्य है कि भाषा डिजाइनरों ने क्षेत्र को ओवरराइड करने की अनुमति दी है। सेटर्स का उपयोग करने का लाभ यह है कि प्रत्येक स्तर अपने स्वयं के राज्य की अखंडता की गारंटी दे सकता है और विश्वास है कि व्युत्पन्न कक्षाओं ने इसे विफल नहीं किया है। फ़ील्ड ओवरराइडिंग सिर्फ परेशानी के लिए पूछ रही है।

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