2012-02-29 16 views
25

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

मुझे लगता है कि वह इस बारे में गलत है, क्योंकि मैंने हमेशा सोचा है कि यदि कोई बात संज्ञा है तो यह एक वस्तु है, और यदि यह एक क्रिया है तो यह एक इंटरफ़ेस है।

उदाहरण के लिए, यदि मैं Bird टाइप करना चाहता था, जहां मैं इसे लागू किए बिना fly विधि को लागू करना चाहता था, तो मैं इसे एक शुद्ध अमूर्त वर्ग बनाउंगा।

अगर मैं Flies टाइप करना चाहता था, तो मैं इसे fly विधि के साथ एक इंटरफ़ेस बनाउंगा।

BirdFlies लागू कर सकता है।

क्या मैं गलत हूँ?

संपादित करें:

केवल ठोस तर्क मैं देखने की मेरी बात का समर्थन करने के दे सकते हैं कि भविष्य में कुछ बिंदु पर डिजाइन इतना बदलने के लिए है कि पक्षियों खा सकते हैं की आवश्यकता हो सकती है। यदि सभी पक्षी समान खाते हैं तो इसे Bird में जोड़ा जाना चाहिए, जिससे इसे शुद्ध शुद्ध अमूर्त बना दिया जा सके।

तो Bird एक अंतरफलक किया गया था, इस परिवर्तन को बस एक बुरा सपना हो सकता है, के बाद से मैं चीजें हैं जो कुछ अन्य आधार वर्ग से विरासत भी मेरी Bird इंटरफ़ेस को लागू है कि क्या पता नहीं कर सकते, तो मैं सिर्फ अपनी समस्याओं दूर refactor नहीं कर सकते।

+0

+1 - अच्छा प्रश्न और मुझे लगता है कि सार वर्गों के उपयोग के लिए आने वाले उत्तरों में कई तर्कसंगत कारणों का पता लगाया जाएगा। –

+3

बस अपने प्रश्न के * भाग * पर उठाएं (इस प्रकार * उत्तर * पोस्ट नहीं कर रहा है): मैं यह नहीं कहूंगा कि इंटरफेस हमेशा * क्रियाएं * हैं। इंटरफेस का उपयोग * बहुत * किया जाता है ताकि कक्षा को दुनिया के सामने एक चेहरा दिखाया जा सके जो कि संज्ञा के रूप में सबसे अच्छा मॉडल है। बस 'java.util' में कुछ इंटरफेस देखें:' तुलनाकर्ता ',' गणना ',' सूची', 'इटरेटर', 'मानचित्र', ... –

+1

राय बैकसाइड्स की तरह हैं, हर किसी को एक मिला है और कुछ बेहतर हैं दूसरों की तुलना में।मुझे विश्वास नहीं है कि व्याकरण के साथ ओओपी की तुलना सही है लेकिन इसके करीब है। इस समरूपता को बढ़ाने के लिए – Lloyd

उत्तर

6

आपके पहले संपादन के अलावा i.e भविष्य की आवश्यकता है। एक संभावित उपयोग-मामला एक निरंतर घोषित कर सकता है और इसे अमूर्त वर्ग में प्रारंभ कर सकता है।

import java.util.ArrayList; 
import java.util.List; 


public abstract class AbstractPure implements ISomeInterface { 
    public static final List<String> days = new ArrayList<String>(); 
    static{ 
     days.add("Monday"); 
     days.add("Tuesday"); 
     days.add("Wednesday");  
     days.add("Thursday"); 
     days.add("Friday"); 
     days.add("Saturday"); 
     days.add("Sunday"); 
    } 
} 
+1

बहुत अच्छा मुद्दा! – sji

+6

तकनीकी रूप से यह अब एक शुद्ध अमूर्त वर्ग नहीं है ... – zmbq

+1

व्यक्तिगत रूप से मुझे लगता है कि इंटरफेस में स्थिरांक अक्सर एक डिजाइन समस्या होती है - कम से कम सब कुछ जिसे प्राइमेटिव्स और एनम्स द्वारा नियंत्रित नहीं किया जा सकता है। लेकिन यह एक मान्य मुद्दा है कि इंटरफेस के साथ यह संभव नहीं है। – Voo

1

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

तो मैं कहूंगा कि यदि आप शुद्ध सार वर्ग का उपयोग कर सकते हैं, तो आप एक इंटरफ़ेस के साथ भी जा सकते हैं, जैसे आपके मित्र ने कहा।

हालांकि, मुझे सी # में एक शुद्ध सार वर्ग की आवश्यकता पूरी नहीं हुई है, इसलिए यह एक काल्पनिक मुद्दा हो सकता है।

+0

मैं एक सी ++ पृष्ठभूमि से आया हूं, जो इस पर मेरी सोच को प्रभावित कर सकता है, फिर मैंने एक सार आधार वर्ग की संभावित आवश्यकता को दर्शाने के लिए प्रश्न बढ़ा दिया है। – sji

+1

हां, लेकिन आप कैसे बता सकते हैं कि अचानक कौन सा इंटरफ़ेस खाना पड़ेगा? – zmbq

0

मैं कहूंगा कि दोनों इंटरफेस और कक्षाएं वस्तुओं को परिभाषित करती हैं। जैसा कि आपने स्वयं कहा था कि क्रियाएं विधियों पर जाती हैं - वे इन वस्तुओं के गुण हैं। फ्लाई के आपके उदाहरण में, मैं एक इंटरफ़ेस FlyingCreature घोषित करूंगा और इसमें एक विधि फ्लाई परिभाषित करूँगा (इस प्रकार आपके पास इंटरफेस जैसे Comparable और SerializableSerialize और Compare नहीं हैं। आपके पास विधि compareTo है)। इसके अलावा आपके अन्य उदाहरण - पक्षी: यदि आपके पास पक्षी के लिए कोई तर्क नहीं है तो आप इसे इंटरफेस के रूप में घोषित करते हैं।

इंटरफेस का उपयोग सामान्य गुणों को घोषित करने के लिए किया जाता है, विभिन्न प्रकार की वस्तुओं के पास, वे उन्हें टैक्सोनोमिक रूप से समूहित करते हैं। बाद में, इस तथ्य का उपयोग करके कि आप जानते हैं कि वे एक ही इंटरफेस के हैं, आप उन्हें उसी तरह संसाधित करने में सक्षम होंगे।

मुझे शुद्ध अमूर्त वर्ग में कोई लाभ नहीं दिख रहा है, क्योंकि मैंने पहले ही कहा है कि अमूर्त वर्ग और इंटरफेस दोनों वस्तुएं घोषित करते हैं।

+0

मैंने पक्षी को एक इंटरफ़ेस बनाने की संभावित कमी को इंगित करने के लिए मेरे प्रश्न का विस्तार किया है। – sji

10

मैं कम से कम एक अच्छा कारण के बारे में सोच सकते हैं: हम एक अंतरफलक अब हम यह सुनिश्चित करें कि के लिए पता है का उपयोग करते हैं मान लें एक वर्ग/इंटरफेस

abstract class/interface Foo { 
    void foo(); 
} 

: आप बाद में सार कक्षाएं विस्तार कर सकते हैं, संगतता पीछे की ओर तोड़ने के बिना फू को अतिरिक्त कार्यक्षमता जोड़ने का कोई तरीका नहीं है। इससे interface Foo2 implements Foo जैसी चीजें हो सकती हैं।

दूसरी ओर आप एक अमूर्त वर्ग आप आसानी से इसे करने के लिए एक और तरीका में जोड़ सकते हैं, जब तक आप एक आधार प्रदान करते हैं कार्यान्वयन है।

ध्यान दें कि जावा 8 इंटरफ़ेस को मूल रूप से एक ही चीज़ करने की अनुमति देगा - लाइब्रेरी लेखकों के लिए उपयोगी होगा जो लैम्बडास का उपयोग करने के लिए अपने पुस्तकालयों को अपडेट करना चाहते हैं, बिना किसी कोड के लाखों लाइनों के लिए संगतता को तोड़ने के लिए।

+0

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

+0

@ एसजी अंत में एक निर्णय कॉल जो वास्तविक व्यापार मामले पर निर्भर करता है, इसलिए स्पष्ट से अलग मुझे बहुत कुछ नहीं दिखता है जो सामान्य रूप से हमारी मदद कर सकता है। कम से कम जावा में यह भी तथ्य है कि कोई भी विरासत नहीं है। जावा 8 के साथ इंटरफेस को विधियों के डिफ़ॉल्ट कार्यान्वयन की अनुमति देने के साथ इसे और अधिक स्पष्ट करने के लिए एक लंबा रास्ता तय करना चाहिए। – Voo

0

मान लें कि आपके पास एक प्लगइन सिस्टम है जो कई प्लगइन प्रकारों के साथ जा रहा है जिनमें से प्रत्येक एक अलग इंटरफ़ेस लागू करता है।

अब, यह भी मदद से आप क्रम में इन प्लगइन कक्षाएं लगाने के लिए प्रतिबिंब का उपयोग कर रहे हैं।

चूंकि वे एक प्लगइन इंटरफेस हैं, कई प्रकार के प्लगइन हो सकते हैं।

आप प्रत्येक प्लगइन एक अमूर्त वर्ग टाइप करते हैं तो आप वंशानुगत पदानुक्रम को नियंत्रित करने और सुनिश्चित कर सकते हैं प्रत्येक प्लगइन एक विशिष्ट प्रकार है।

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

0

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

तो अपने उदाहरण एक पक्षी का उपयोग कर एक अमूर्त वर्ग होगा।

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

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

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