RealNumber और ComplexNumber विरासत को कैसे लागू करें?


11

उम्मीद है कि बहुत अकादमिक नहीं ...

मान लीजिए कि मुझे अपनी SW लाइब्रेरी में वास्तविक और जटिल संख्याएँ चाहिए।

आधार -ए (या यहाँ ) संबंध के आधार पर , वास्तविक संख्या एक जटिल संख्या होती है, जहाँ जटिल संख्या के काल्पनिक भाग में b केवल 0 होता है।

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

इसके अलावा एक राय है, कि विरासत बुराई है

मुझे कल की तरह याद है, जब मैं विश्वविद्यालय में ओओपी सीख रहा था, मेरे प्रोफेसर ने कहा, यह विरासत का एक अच्छा उदाहरण नहीं है क्योंकि उन दोनों के निरपेक्ष मूल्य को अलग-अलग गणना की जाती है (लेकिन इसके लिए हमारे पास विधि अधिभार / बहुरूपता है, सही है? ..?) ।

मेरा अनुभव है, कि हम अक्सर DRY को हल करने के लिए इनहेरिटेंस का उपयोग करते हैं, जिसके परिणामस्वरूप हम पदानुक्रम में अक्सर कृत्रिम सार वर्ग होते हैं (हमें अक्सर नाम खोजने के लिए समस्या होती है क्योंकि वे वास्तविक दुनिया से वस्तुओं का प्रतिनिधित्व नहीं करते हैं)।


7
यह पूर्व प्रश्न में शामिल जैसा दिखता है: क्या आयत को वर्ग से प्राप्त किया जाना चाहिए?
gnat

1
@gnat ओह यार, यह एक और उदाहरण था जिसका मैं उपयोग करना चाहता था ... धन्यवाद!
बेतालिस्ता

7
... ध्यान दें कि गणितीय अर्थ में वाक्य "वास्तविक संख्या एक जटिल संख्या है" केवल अपरिवर्तनीय संख्याओं के लिए मान्य है , इसलिए यदि आप अपरिवर्तनीय वस्तुओं का उपयोग करते हैं, तो आप एलएसपी उल्लंघन से बच सकते हैं (वर्गों और आयतों के लिए भी वही होल्ड है, इसे देखें) अतः उत्तर )।
डॉक्टर ब्राउन

5
... ध्यान दें कि जटिल संख्याओं के लिए पूर्ण मान गणना वास्तविक संख्याओं के लिए भी काम करती है, इसलिए मुझे यकीन नहीं है कि आपके प्रोफेसर का क्या मतलब है। यदि आप एक अपरिवर्तनीय जटिल संख्या में "Abs ()" विधि को सही ढंग से लागू करते हैं और इससे "वास्तविक" प्राप्त करते हैं, तो ABS () विधि अभी भी सही परिणाम देगी।
डॉक्टर ब्राउन

जवाबों:


17

यहां तक ​​कि अगर गणितीय अर्थों में, एक वास्तविक संख्या एक जटिल संख्या है, तो जटिल से वास्तविक प्राप्त करना एक अच्छा विचार नहीं है। यह लिस्कोव प्रतिस्थापन सिद्धांत (अन्य बातों के अलावा) का उल्लंघन करता है कि एक व्युत्पन्न वर्ग को आधार वर्ग के गुणों को नहीं छिपाना चाहिए।

इस मामले में एक वास्तविक संख्या को जटिल संख्या के काल्पनिक भाग को छिपाना होगा। यह स्पष्ट है कि किसी छिपे हुए फ्लोटिंग पॉइंट नंबर (काल्पनिक भाग) को स्टोर करने का कोई मतलब नहीं है अगर आपको केवल वास्तविक हिस्से की आवश्यकता है।

यह मूल रूप से एक टिप्पणी में उल्लिखित आयत / वर्ग उदाहरण के समान मुद्दा है।


2
आज मैंने कई बार इस "Liskow प्रतिस्थापन सिद्धांत" को देखा, मुझे इसके बारे में अधिक पढ़ना होगा, क्योंकि मुझे यह नहीं पता है।
बेटलिस्टा

7
वास्तविक संख्या के काल्पनिक भाग को शून्य के रूप में रिपोर्ट करना पूरी तरह से ठीक है, उदाहरण के लिए केवल-पढ़ने की विधि के माध्यम से। लेकिन यह एक वास्तविक संख्या को एक जटिल संख्या के रूप में लागू करने के लिए कोई मतलब नहीं है जहां काल्पनिक भाग शून्य पर सेट है। यह वास्तव में एक ऐसा मामला है जहां वंशानुक्रम भ्रामक है: जबकि इंटरफ़ेस वंशानुक्रम यकीनन यहां ठीक होगा, कार्यान्वयन विरासत में एक समस्याग्रस्त डिजाइन होगा।
आमोन

4
यह सही समझ में आता है कि वास्तविक संख्या जटिल संख्या से विरासत में मिली है, जब तक कि दोनों अपरिवर्तनीय नहीं हैं। और आप ओवरहेड को बुरा नहीं मानते।
Deduplicator

@ डेडप्लिकेटर: दिलचस्प बिंदु। अपरिपक्वता बहुत सारे मुद्दों को हल करती है लेकिन मैं इस मामले में अभी तक पूरी तरह आश्वस्त नहीं हूं। इसके बारे में सोचना होगा।
फ्रैंक पफर

3

उन दोनों के निरपेक्ष मूल्य के रूप में विरासत का एक अच्छा उदाहरण अलग से गणना नहीं किया गया है

यह वास्तव में यहाँ सभी विरासत के खिलाफ एक सम्मोहक कारण नहीं है, बस प्रस्तावित class RealNumber<-> class ComplexNumberमॉडल।

आप यथोचित एक अंतरफलक परिभाषित कर सकता है Number, जो दोनों RealNumber और ComplexNumberलागू करेगा।

जो दिख सकता है

interface Number
{
    Number Add(Number rhs);
    Number Subtract(Number rhs);
    // ... etc
}

लेकिन फिर आप Numberइन परिचालनों में अन्य मापदंडों को बाध्य करने के लिए उसी तरह का व्युत्पन्न होना thisचाहते हैं, जिसके साथ आप निकट हो सकते हैं

interface Number<T>
{
    Number<T> Add(Number<T> rhs);
    Number<T> Subtract(Number<T> rhs);
    // ... etc
}

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

complex operator + (complex lhs, complex rhs);
complex operator - (complex lhs, complex rhs);
// ... etc

Number frobnicate<Number>(List<Number> foos, Number bar); // uses arithmetic operations

0

समाधान: सार्वजनिक RealNumberवर्ग न हो

मुझे यह पूरी तरह से ठीक लगेगा यदि ComplexNumberएक स्थिर कारखाना विधि होती fromDouble(double)जो एक जटिल संख्या को काल्पनिक शून्य के साथ वापस कर देती। फिर आप उन सभी परिचालनों का उपयोग कर सकते हैं जो आप RealNumberइस ComplexNumberउदाहरण पर उपयोग करेंगे ।

लेकिन मुझे यह देखने में परेशानी होती है कि आपको एक सार्वजनिक विरासत वाले RealNumberवर्ग की आवश्यकता क्यों होगी । आमतौर पर इन कारणों के लिए वंशानुक्रम का उपयोग किया जाता है (मेरे सिर से बाहर, मुझे सही करें अगर कुछ छूट गया है)

  • व्यवहार का विस्तार। RealNumbersकोई अतिरिक्त संचालन जटिल संख्या नहीं कर सकती है, इसलिए ऐसा करने का कोई मतलब नहीं है।

  • एक विशिष्ट कार्यान्वयन के साथ अमूर्त व्यवहार को लागू करना। चूंकि ComplexNumberअमूर्त नहीं होना चाहिए, यह भी लागू नहीं होता है।

  • कोड का पुन: उपयोग यदि आप सिर्फ ComplexNumberकक्षा का उपयोग करते हैं तो आप 100% कोड का पुन: उपयोग करते हैं ।

  • किसी विशिष्ट कार्य के लिए अधिक विशिष्ट / कुशल / सटीक कार्यान्वयन। यह यहां लागू किया जा सकता है, RealNumbersकुछ कार्यक्षमताओं को तेजी से लागू कर सकता है। लेकिन फिर इस उपवर्ग को स्थैतिक के पीछे छिपाया fromDouble(double)जाना चाहिए और इसे बाहर नहीं जाना चाहिए। इस तरह इसे काल्पनिक भाग को छिपाने की आवश्यकता नहीं होगी। बाहर के लिए केवल जटिल संख्याएं होनी चाहिए (जो वास्तविक संख्याएं हैं)। आप इस निजी RealNumber वर्ग को किसी भी संक्रिया से उस जटिल संख्या वर्ग में भी लौटा सकते हैं जिसका परिणाम वास्तविक संख्या में होता है। (यह मानता है कि कक्षाएं अधिकांश संख्या वर्गों के रूप में अपरिवर्तनीय हैं।)

यह इंटेगर के एक उपवर्ग को लागू करने जैसा है जिसे शून्य कहा जाता है और कुछ संचालन हार्डकोड करते हैं क्योंकि वे शून्य के लिए तुच्छ हैं। आप ऐसा कर सकते हैं, क्योंकि प्रत्येक शून्य एक पूर्णांक है, लेकिन इसे सार्वजनिक न करें, इसे फ़ैक्टरी विधि के पीछे छिपाएं।


मैं कुछ निराश नहीं हूं, क्योंकि मेरे पास साबित करने के लिए कोई स्रोत नहीं है। इसके अलावा अगर किसी और को अंदाजा नहीं था, तो मुझे हमेशा संदेह है कि इसका कोई कारण हो सकता है। लेकिन कृपया मुझे बताएं कि आपको क्यों लगता है कि यह गलत है और आप इसे बेहतर कैसे बनाएंगे।
Findusl

0

यह कहना कि एक वास्तविक संख्या एक जटिल संख्या है, कंप्यूटर विज्ञान की तुलना में गणित, विशेष रूप से निर्धारित सिद्धांत में अधिक अर्थ रखती है।
गणित में हम कहते हैं:

  • एक वास्तविक संख्या एक जटिल संख्या है क्योंकि जटिल संख्याओं के समुच्चय में वास्तविक संख्याओं का समूह शामिल होता है।
  • एक परिमेय संख्या एक वास्तविक संख्या है क्योंकि वास्तविक संख्याओं के समुच्चय में परिमेय संख्याओं का सेट (और अपरिमेय संख्याओं का समूह) शामिल होता है।
  • पूर्णांक एक परिमेय संख्या है क्योंकि परिमेय संख्याओं के समुच्चय में पूर्णांकों का समुच्चय शामिल होता है।

हालांकि, इसका मतलब यह नहीं है कि आपको रियल लाइब्रेरी और कॉम्प्लेक्सनंबर क्लास को शामिल करने के लिए अपनी लाइब्रेरी को डिज़ाइन करते समय विरासत का उपयोग करना चाहिए या करना चाहिए। में प्रभावी जावा, द्वितीय संस्करण यहोशू बलोच द्वारा; आइटम 16 "एहसान रचना पर एहसान रचना" है। उस आइटम में बताई गई समस्याओं से बचने के लिए, जब आपके पास आपका RealNumber क्लास परिभाषित हो, तो इसका उपयोग आपके ComplexNumber वर्ग में किया जा सकता है:

public class ComplexNumber {
    private RealNumber realPart;
    private RealNumber imaginaryPart;

    // Implementation details are for you to write
}

यह आपको जोशुआ बलोच द्वारा पहचाने गए मुद्दों से बचने के दौरान अपने कोड DRY को रखने के लिए अपने RealNumber वर्ग के पुन: उपयोग की सारी शक्ति देता है।


0

यहां दो समस्याएं हैं। पहला यह है कि कंटेनरों के प्रकार और उनकी सामग्री के प्रकारों के लिए समान शब्दों का उपयोग करना आम है, विशेष रूप से आदिम प्रकार के साथ। doubleउदाहरण के लिए, शब्द का उपयोग डबल-परिशुद्धता फ़्लोटिंग-पॉइंट मान और एक कंटेनर जिसमें किसी को संग्रहीत किया जा सकता है, दोनों का वर्णन करने के लिए किया जाता है।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.