java - जावा ऑपरेटर ओवरलोडिंग क्यों नहीं देता है?




c++ operator-overloading (10)

Boost.Units देखें: लिंक टेक्स्ट

यह ऑपरेटर ओवरलोडिंग के माध्यम से शून्य-ओवरहेड आयामी विश्लेषण प्रदान करता है। यह कितना स्पष्ट हो सकता है?

quantity<force>     F = 2.0*newton;
quantity<length>    dx = 2.0*meter;
quantity<energy>    E = F * dx;
std::cout << "Energy = " << E << endl;

वास्तव में "ऊर्जा = 4 जे" आउटपुट होगा जो सही है।

सी ++ से जावा तक आ रहा है, स्पष्ट अनुत्तरित प्रश्न यह है कि जावा में ऑपरेटर ओवरलोडिंग क्यों नहीं थी?

Complex a, b, c; a = b + c; Complex a, b, c; a = b + c; Complex a, b, c; a = b.add(c); से काफी सरल Complex a, b, c; a = b.add(c); Complex a, b, c; a = b.add(c); ?

ऑपरेटर ओवरलोडिंग की अनुमति देने के लिए वैध तर्क हैं, इसके लिए कोई ज्ञात कारण है? क्या मनमाना कारण है, या समय के लिए खो गया है?


ऑपरेटर अधिभार के बारे में शिकायत करने वाली कई पोस्ट हैं।

मुझे लगा कि मुझे "ऑपरेटर ओवरलोडिंग" अवधारणाओं को स्पष्ट करना था, इस अवधारणा पर वैकल्पिक दृष्टिकोण प्रदान करना।

कोड obfuscating?

यह तर्क एक झूठ है।

सभी भाषाओं में Obfuscating संभव है ...

कार्य या विधियों के माध्यम से सी या जावा में कोड को खराब करना उतना ही आसान है जितना कि ऑपरेटर ओवरलोड के माध्यम से सी ++ में है:

// C++
T operator + (const T & a, const T & b) // add ?
{
   T c ;
   c.value = a.value - b.value ; // subtract !!!
   return c ;
}

// Java
static T add (T a, T b) // add ?
{
   T c = new T() ;
   c.value = a.value - b.value ; // subtract !!!
   return c ;
}

/* C */
T add (T a, T b) /* add ? */
{
   T c ;
   c.value = a.value - b.value ; /* subtract !!! */
   return c ;
}

... जावा के मानक इंटरफेस में भी

एक और उदाहरण के लिए, चलिए जावा में Cloneable इंटरफेस देखें:

आपको इस इंटरफेस को लागू करने वाली वस्तु को क्लोन करना होगा। लेकिन आप झूठ बोल सकते हैं। और एक अलग वस्तु बनाएँ। वास्तव में, यह इंटरफ़ेस इतना कमजोर है कि आप इसे किसी अन्य प्रकार की ऑब्जेक्ट को पूरी तरह से वापस कर सकते हैं, बस इसके मजाक के लिए:

class MySincereHandShake implements Cloneable
{
    public Object clone()
    {
       return new MyVengefulKickInYourHead() ;
    }
}

चूंकि Cloneable इंटरफ़ेस का दुरुपयोग / obfuscated किया जा सकता है, क्या इसे उसी आधार पर प्रतिबंधित किया जाना चाहिए C ++ ऑपरेटर ओवरलोडिंग माना जाता है?

हम दिन के MyComplexNumber घंटे को वापस करने के लिए MyComplexNumber क्लास की toString() विधि को MyComplexNumber कर सकते हैं। क्या toString() अधिभार पर प्रतिबंध लगा दिया जाना चाहिए, भी? हम MyComplexNumber.equals को एक यादृच्छिक मान वापस करने, ऑपरेटरों को संशोधित करने आदि आदि को तोड़ सकते हैं ..

जावा में, सी ++, या जो भी भाषा में, प्रोग्रामर को कोड लिखते समय कम से कम अर्थशास्त्र का सम्मान करना चाहिए। इसका अर्थ यह है कि एक add फ़ंक्शन लागू करना जो क्लोन करने Cloneable कार्यान्वयन विधि और Cloneable कार्यान्वयन विधि है, और वृद्धि ++ ऑपरेटर वृद्धि से।

क्या वैसे भी obfuscating है?

अब जब हम जानते हैं कि प्राचीन जावा विधियों के माध्यम से भी कोड को तोड़ दिया जा सकता है, तो हम खुद को सी ++ में ऑपरेटर ओवरलोडिंग के वास्तविक उपयोग के बारे में पूछ सकते हैं?

स्पष्ट और प्राकृतिक नोटेशन: विधियों बनाम ऑपरेटर अधिभार?

अलग-अलग मामलों के लिए, जावा और सी ++ में "समान" कोड के नीचे हम तुलना करेंगे, इस बारे में एक विचार है कि किस प्रकार की कोडिंग शैली स्पष्ट है।

प्राकृतिक तुलना:

// C++ comparison for built-ins and user-defined types
bool    isEqual          = A == B ;
bool    isNotEqual       = A != B ;
bool    isLesser         = A <  B ;
bool    isLesserOrEqual  = A <= B ;

// Java comparison for user-defined types
boolean isEqual          = A.equals(B) ;
boolean isNotEqual       = ! A.equals(B) ;
boolean isLesser         = A.comparesTo(B) < 0 ;
boolean isLesserOrEqual  = A.comparesTo(B) <= 0 ;

कृपया ध्यान दें कि ए और बी सी ++ में किसी भी प्रकार का हो सकता है, जब तक ऑपरेटर ओवरलोड प्रदान किए जाते हैं। जावा में, जब ए और बी प्राइमेटिव नहीं होते हैं, तो कोड आदिम जैसी वस्तुओं (बिगइंटर, इत्यादि) के लिए भी बहुत भ्रमित हो सकता है ...

प्राकृतिक सरणी / कंटेनर एक्सेसर्स और सबस्क्रिप्टिंग:

// C++ container accessors, more natural
value        = myArray[25] ;         // subscript operator
value        = myVector[25] ;        // subscript operator
value        = myString[25] ;        // subscript operator
value        = myMap["25"] ;         // subscript operator
myArray[25]  = value ;               // subscript operator
myVector[25] = value ;               // subscript operator
myString[25] = value ;               // subscript operator
myMap["25"]  = value ;               // subscript operator

// Java container accessors, each one has its special notation
value        = myArray[25] ;         // subscript operator
value        = myVector.get(25) ;    // method get
value        = myString.charAt(25) ; // method charAt
value        = myMap.get("25") ;     // method get
myArray[25]  = value ;               // subscript operator
myVector.set(25, value) ;            // method set
myMap.put("25", value) ;             // method put

जावा में, हम देखते हैं कि प्रत्येक कंटेनर के लिए एक ही चीज़ (एक इंडेक्स या पहचानकर्ता के माध्यम से अपनी सामग्री तक पहुंच) के लिए, हमारे पास ऐसा करने का एक अलग तरीका है, जो भ्रमित है।

सी ++ में, ऑपरेटर ओवरलोडिंग के लिए धन्यवाद, प्रत्येक कंटेनर अपनी सामग्री तक पहुंचने के लिए उसी तरह उपयोग करता है।

प्राकृतिक उन्नत प्रकार हेरफेर

नीचे दिए गए उदाहरण " मैट्रिक्स ऑब्जेक्ट " और " सी ++ मैट्रिक्स ऑब्जेक्ट " के लिए Google पर पाए गए पहले लिंक का उपयोग करके मिले Matrix ऑब्जेक्ट का उपयोग करते हैं:

// C++ YMatrix matrix implementation on CodeProject
// http://www.codeproject.com/KB/architecture/ymatrix.aspx
// A, B, C, D, E, F are Matrix objects;
E =  A * (B / 2) ;
E += (A - B) * (C + D) ;
F =  E ;                  // deep copy of the matrix

// Java JAMA matrix implementation (seriously...)
// http://math.nist.gov/javanumerics/jama/doc/
// A, B, C, D, E, F are Matrix objects;
E = A.times(B.times(0.5)) ;
E.plusEquals(A.minus(B).times(C.plus(D))) ;
F = E.copy() ;            // deep copy of the matrix

और यह matrices तक ही सीमित नहीं है। BigInteger और BigDecimal कक्षाएं एक ही भ्रमित शब्दशः से पीड़ित हैं, जबकि सी ++ में उनके समकक्ष अंतर्निहित प्रकार के रूप में स्पष्ट हैं।

प्राकृतिक iterators:

// C++ Random Access iterators
++it ;                  // move to the next item
--it ;                  // move to the previous item
it += 5 ;               // move to the next 5th item (random access)
value = *it ;           // gets the value of the current item
*it = 3.1415 ;          // sets the value 3.1415 to the current item
(*it).foo() ;           // call method foo() of the current item

// Java ListIterator<E> "bi-directional" iterators
value = it.next() ;     // move to the next item & return the value
value = it.previous() ; // move to the previous item & return the value
it.set(3.1415) ;        // sets the value 3.1415 to the current item

प्राकृतिक मवेशी:

// C++ Functors
myFunctorObject("Hello World", 42) ;

// Java Functors ???
myFunctorObject.execute("Hello World", 42) ;

पाठ सम्मेलन:

// C++ stream handling (with the << operator)
                    stringStream   << "Hello " << 25 << " World" ;
                    fileStream     << "Hello " << 25 << " World" ;
                    outputStream   << "Hello " << 25 << " World" ;
                    networkStream  << "Hello " << 25 << " World" ;
anythingThatOverloadsShiftOperator << "Hello " << 25 << " World" ;

// Java concatenation
myStringBuffer.append("Hello ").append(25).append(" World") ;

ठीक है, जावा में आप MyString = "Hello " + 25 + " World" ; उपयोग कर सकते हैं MyString = "Hello " + 25 + " World" ; भी ... लेकिन, एक सेकंड प्रतीक्षा करें: यह ऑपरेटर ओवरलोडिंग है, है ना? क्या यह धोखा नहीं है ???

:-D

जेनेरिक कोड?

समान जेनेरिक कोड ऑपरेटिंग ऑपरेटरों को अंतर्निर्मित / प्राइमेटिव्स (जिनमें जावा में कोई इंटरफेस नहीं है), मानक ऑब्जेक्ट्स (जो सही इंटरफ़ेस नहीं हो सकता), और उपयोगकर्ता द्वारा परिभाषित ऑब्जेक्ट्स दोनों के लिए उपयोग योग्य होना चाहिए।

उदाहरण के लिए, मनमानी प्रकारों के दो मानों के औसत मूल्य की गणना करना:

// C++ primitive/advanced types
template<typename T>
T getAverage(const T & p_lhs, const T & p_rhs)
{
   return (p_lhs + p_rhs) / 2 ;
}

int     intValue     = getAverage(25, 42) ;
double  doubleValue  = getAverage(25.25, 42.42) ;
complex complexValue = getAverage(cA, cB) ; // cA, cB are complex
Matrix  matrixValue  = getAverage(mA, mB) ; // mA, mB are Matrix

// Java primitive/advanced types
// It won't really work in Java, even with generics. Sorry.

ऑपरेटर ओवरलोडिंग पर चर्चा

अब हमने ऑपरेटर ओवरलोडिंग और जावा में एक ही कोड का उपयोग कर सी ++ कोड के बीच उचित तुलना देखी है, अब हम एक अवधारणा के रूप में "ऑपरेटर ओवरलोडिंग" पर चर्चा कर सकते हैं।

कंप्यूटर से पहले ऑपरेटर अधिभार अस्तित्व में था

कंप्यूटर विज्ञान के बाहर भी, ऑपरेटर ओवरलोडिंग है: उदाहरण के लिए, गणित में, ऑपरेटरों जैसे + , - , * , आदि अधिभारित होते हैं।

दरअसल, + , - , * , आदि का संकेत ऑपरेंड के प्रकार (संख्यात्मक, वैक्टर, क्वांटम तरंग कार्य, matrices, आदि) के आधार पर बदलता है।

हमारे विज्ञान पाठ्यक्रमों के हिस्से के रूप में, हम में से अधिकांश ने ऑपरेटरों के प्रकारों के आधार पर ऑपरेटरों के लिए कई संकेतों को सीखा। क्या हमने उन्हें भ्रमित कर दिया, उन्हें?

ऑपरेटर ओवरलोडिंग अपने ऑपरेटरों पर निर्भर करता है

ऑपरेटर ओवरलोडिंग का यह सबसे महत्वपूर्ण हिस्सा है: गणित की तरह, या भौतिकी में, ऑपरेशन अपने ऑपरेटरों के प्रकारों पर निर्भर करता है।

तो, ऑपरेंड के प्रकार को जानें, और आप ऑपरेशन के प्रभाव को जानेंगे।

यहां तक ​​कि सी और जावा में (हार्ड-कोडेड) ऑपरेटर ओवरलोडिंग है

सी में, ऑपरेटर का असली व्यवहार इसके संचालन के अनुसार बदल जाएगा। उदाहरण के लिए, दो पूर्णांक जोड़ना दो युगल, या यहां तक ​​कि एक पूर्णांक और एक डबल जोड़ने से अलग है। यहां तक ​​कि संपूर्ण सूचक अंकगणितीय डोमेन भी है (बिना कास्टिंग के, आप एक सूचक को एक पूर्णांक में जोड़ सकते हैं, लेकिन आप दो पॉइंटर्स नहीं जोड़ सकते हैं ...)।

जावा में, कोई पॉइंटर अंकगणित नहीं है, लेकिन किसी को भी ऑपरेटर के बिना स्ट्रिंग कॉन्सटेनेशन मिला है, "ऑपरेटर ओवरलोडिंग बुराई" पंथ में अपवाद को न्यायसंगत साबित करने के लिए पर्याप्त हास्यास्पद होगा।

यह सिर्फ इतना है कि आप सी (ऐतिहासिक कारणों से) या जावा ( व्यक्तिगत कारणों से , नीचे देखें) कोडर के रूप में, आप अपना खुद का प्रदान नहीं कर सकते हैं।

सी ++ में, ऑपरेटर ओवरलोडिंग वैकल्पिक नहीं है ...

सी ++ में, अंतर्निर्मित प्रकारों के लिए ऑपरेटर ओवरलोडिंग संभव नहीं है (और यह एक अच्छी बात है), लेकिन उपयोगकर्ता द्वारा परिभाषित प्रकारों में उपयोगकर्ता द्वारा परिभाषित ऑपरेटर ओवरलोड हो सकते हैं।

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

सच्चाई यह है कि, toString() , clone() , equals() विधियों जावा ( यानी अर्ध-मानक-जैसे ) के लिए हैं, सी ++ ऑपरेटर ओवरलोडिंग सी ++ का इतना हिस्सा है कि यह मूल सी ऑपरेटरों के रूप में स्वाभाविक हो जाता है , या पहले उल्लिखित जावा विधियों।

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

... लेकिन इसका दुरुपयोग नहीं किया जाना चाहिए

ऑपरेटर ओवरलोडिंग ऑपरेटर के अर्थशास्त्र का सम्मान करने का प्रयास करना चाहिए। एक + ऑपरेटर में घटाएं (जैसा कि "एक add फ़ंक्शन में घटाएं" या " clone विधि में रिटर्न क्रैप" में)।

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

तो ... ठीक है ... फिर जावा में यह क्यों संभव नहीं है?

क्योंकि जेम्स गोस्लिंग ने ऐसा कहा था:

मैंने ऑपरेटर ओवरलोडिंग को काफी व्यक्तिगत पसंद के रूप में छोड़ दिया क्योंकि मैंने देखा कि बहुत से लोग इसे C ++ में दुरुपयोग करते हैं।

जेम्स गोस्लिंग स्रोत: http://www.gotw.ca/publications/c_family_interview.htm

कृपया नीचे स्ट्रॉस्ट्रप के साथ गोस्लिंग के पाठ की तुलना करें:

कई सी ++ डिज़ाइन निर्णयों में उनकी जड़ें नापसंद होती हैं ताकि लोगों को किसी विशेष तरीके से चीजों को करने के लिए मजबूर किया जा सके [...] अक्सर, मैं एक ऐसी सुविधा को दूर करने का लुत्फ उठाता हूं जिसे मैं व्यक्तिगत रूप से नापसंद करता हूं, मैंने ऐसा करने से रोका क्योंकि मुझे नहीं लगता था कि मेरे पास दूसरों पर मेरे विचारों को मजबूर करने का अधिकार

Bjarne Stroustrup। स्रोत: सी ++ का वर्णन और विकास (1.3 सामान्य पृष्ठभूमि)

ऑपरेटर ओवरलोडिंग लाभ जावा होगा?

कुछ ऑब्जेक्ट्स ऑपरेटर ओवरलोडिंग (कंक्रीट या न्यूमेरिकल टाइप, जैसे बिगडेसिमल, कॉम्प्लेक्स नंबर, मैट्रिस, कंटेनर, इटरेटर, तुलनित्र, पार्सर्स इत्यादि) से बहुत लाभान्वित होंगे।

सी ++ में, आप स्ट्रॉस्ट्रप की नम्रता के कारण इस लाभ से लाभ प्राप्त कर सकते हैं। जावा में, आप गोस्लिंग की व्यक्तिगत पसंद के कारण बस खराब हो गए हैं

क्या इसे जावा में जोड़ा जा सकता है?

जावा में अब ऑपरेटर ओवरलोडिंग जोड़ने के कारण आंतरिक राजनीति का मिश्रण नहीं हो सकते हैं, फीचर के लिए एलर्जी, डेवलपर्स का अविश्वास (आप जानते हैं, जो सैबोटूर हैं जो जावा टीमों को परेशान करते हैं ...), पिछले जेवीएम के साथ संगतता, एक सही विनिर्देश लिखने के लिए समय, आदि ..

तो इस सुविधा के लिए अपनी सांस का इंतजार न करें ...

लेकिन वे इसे सी # में करते हैं !!!

हाँ ...

हालांकि यह दो भाषाओं के बीच एकमात्र अंतर होने से बहुत दूर है, यह कभी भी मुझे खुश करने में विफल रहता है।

जाहिर है, सी # लोग, उनके "प्रत्येक आदिम एक struct , और ऑब्जेक्ट से एक struct प्राप्त होती है" , इसे पहली बार कोशिश करने के लिए सही मिला।

और वे इसे अन्य भाषाओं में करते हैं !!!

प्रयुक्त परिभाषित ऑपरेटर ओवरलोडिंग के खिलाफ सभी एफयूडी के बावजूद, निम्नलिखित भाषाएं इसका समर्थन करती हैं: Scala , Dart , Python , F# , C# , D , अल्गोल 68 , Smalltalk , Groovy , पर्ल 6 , सी ++, Ruby , Haskell , MATLAB , Eiffel , Lua , Clojure , फोरट्रान 9 0 , Swift , Ada , डेल्फी 2005 ...

इतनी सारी भाषाएं, कई अलग-अलग (और कभी-कभी विरोधी) दर्शन के साथ, और फिर भी वे सभी उस बिंदु पर सहमत हैं।

सोच के लिए भोजन...


खैर आप वास्तव में ऑपरेटर ओवरलोडिंग के साथ पैर में खुद को गोली मार सकते हैं। यह पॉइंटर्स के समान है कि लोग उनके साथ बेवकूफ गलतियां करते हैं और इसलिए कैंची को दूर करने का फैसला किया गया।

कम से कम मुझे लगता है कि यही कारण है। मैं वैसे भी आपकी तरफ हूँ। :)


जावा डिजाइनरों ने फैसला किया कि ऑपरेटर ओवरलोडिंग इसके लायक होने की तुलना में अधिक परेशानी थी। इतना ही आसान।

ऐसी भाषा में जहां प्रत्येक ऑब्जेक्ट वैरिएबल वास्तव में एक संदर्भ है, कम से कम एक सी ++ प्रोग्रामर के लिए ऑपरेटर अधिभार को काफी अजीब होने का अतिरिक्त खतरा मिलता है। सी # के == ऑपरेटर ओवरलोडिंग और Object.Equals साथ स्थिति की तुलना करें। Object.Equals और Object.Equals (या जिसे भी कहा जाता है)।


तकनीकी रूप से, प्रत्येक प्रोग्रामिंग भाषा में ऑपरेटर ओवरलोडिंग होता है जो विभिन्न प्रकार की संख्याओं, जैसे पूर्णांक और वास्तविक संख्याओं से निपट सकता है। स्पष्टीकरण: अधिभार शब्द का अर्थ है कि एक समारोह के लिए केवल कई कार्यान्वयन हैं। अधिकांश प्रोग्रामिंग भाषाओं में ऑपरेटर + के लिए विभिन्न कार्यान्वयन प्रदान किए जाते हैं, एक पूर्णांक के लिए, एक वास्तविक के लिए, इसे ऑपरेटर ओवरलोडिंग कहा जाता है।

अब, बहुत से लोगों को यह अजीब लगता है कि जावा ऑपरेटर के लिए ऑपरेटर ओवरलोडिंग है + स्ट्रिंग्स को एक साथ जोड़ने के लिए, और गणितीय दृष्टिकोण से यह वास्तव में अजीब होगा, लेकिन प्रोग्रामिंग भाषा के डेवलपर के दृष्टिकोण से देखा गया है, बिल्टिन ऑपरेटर ओवरलोडिंग जोड़ने में कुछ भी गलत नहीं है ऑपरेटर के लिए + अन्य वर्गों जैसे स्ट्रिंग के लिए। हालांकि, ज्यादातर लोग इस बात से सहमत हैं कि एक बार जब आप स्ट्रिंग के लिए + के लिए बिल्टिन ओवरलोडिंग जोड़ते हैं, तो आमतौर पर डेवलपर के लिए यह कार्यक्षमता प्रदान करना एक अच्छा विचार है।

ऑपरेटर ओवरलोडिंग कोड को ओवरफ्लोकेट करने वाली फॉरेसी के साथ पूरी तरह से असहमत है, क्योंकि यह डेवलपर को निर्णय लेने के लिए छोड़ दिया गया है। यह सोचने के लिए भद्दा है, और काफी ईमानदार होने के लिए, यह पुराना हो रहा है।

जावा 8 में ऑपरेटर ओवरलोडिंग जोड़ने के लिए +1।


मान लीजिए कि आप किसी ऑब्जेक्ट के पिछले मान को ओवरराइट करना चाहते हैं, तो एक सदस्य फ़ंक्शन को लागू करना होगा।

Complex a, b, c;
// ...
a = b.add(c);

सी ++ में, यह अभिव्यक्ति संकलक को स्टैक पर तीन (3) ऑब्जेक्ट्स बनाने, अतिरिक्त करने के लिए बताती है, और परिणामी मान को अस्थायी ऑब्जेक्ट से मौजूदा ऑब्जेक्ट में कॉपी करती a

हालांकि, जावा में, operator= संदर्भ प्रकारों के लिए मान प्रतिलिपि नहीं करता है, और उपयोगकर्ता केवल नए प्रकार के प्रकार बना सकते हैं, मूल्य प्रकार नहीं। तो Complex नामक उपयोगकर्ता द्वारा परिभाषित प्रकार के लिए, असाइनमेंट का मतलब किसी मौजूदा मान के संदर्भ की प्रतिलिपि बनाना है।

इसके बजाय विचार करें:

b.set(1, 0); // initialize to real number '1'
a = b; 
b.set(2, 0);
assert( !a.equals(b) );

सी ++ में, यह मान की प्रतिलिपि बनाता है, इसलिए तुलना परिणाम बराबर नहीं होगी। जावा में, operator= संदर्भ प्रतिलिपि करता है, इसलिए a और b अब एक ही मान का जिक्र कर रहे हैं। नतीजतन, तुलना 'बराबर' उत्पन्न करेगी, क्योंकि वस्तु स्वयं के बराबर तुलना करेगी।

प्रतियों और संदर्भों के बीच अंतर केवल ऑपरेटर ओवरलोडिंग के भ्रम में जोड़ता है। जैसा कि @ सेबेस्टियन ने उल्लेख किया है, जावा और सी # दोनों को अलग-अलग मूल्य और संदर्भ समानता से निपटना होगा - operator+ मूल्यों और वस्तुओं से निपटने की संभावना है, लेकिन operator= पहले ही संदर्भों से निपटने के लिए लागू किया गया है।

सी ++ में, आपको केवल एक समय में एक तरह की तुलना करना चाहिए, इसलिए यह कम भ्रमित हो सकता है। उदाहरण के लिए, Complex पर, operator= और operator== दोनों मूल्यों पर काम कर रहे हैं - मूल्यों की प्रतिलिपि बनाना और मूल्यों की तुलना क्रमशः।


यह कहकर कि ऑपरेटर ओवरलोडिंग उस प्रकार की तार्किक त्रुटियों की ओर ले जाती है जो ऑपरेटर ऑपरेशन तर्क से मेल नहीं खाता है, यह कुछ भी कहने जैसा नहीं है। ऑपरेशन तर्क के लिए फ़ंक्शन नाम अनुचित होने पर एक ही प्रकार की त्रुटि उत्पन्न होगी - तो समाधान क्या है: फ़ंक्शन उपयोग की क्षमता ड्रॉप करें !? यह एक हास्यपूर्ण उत्तर है - "ऑपरेशन तर्क के लिए अनुचित", प्रत्येक पैरामीटर नाम, प्रत्येक वर्ग, फ़ंक्शन या जो भी तर्कसंगत अनुचित हो सकता है। मुझे लगता है कि यह विकल्प सम्मानजनक प्रोग्रामिंग भाषा में उपलब्ध होना चाहिए, और जो लोग सोचते हैं कि यह असुरक्षित है - अरे, कोई भी नहीं कहता है कि आपको इसका उपयोग करना है। चलो सी # लेते हैं। उन्होंने पॉइंटर्स को डूप्ड किया लेकिन हे - वहां 'असुरक्षित कोड' कथन है - प्रोग्राम जैसा कि आप अपने जोखिम पर पसंद करते हैं।


Groovy के ऑपरेटर ओवरलोडिंग है, और जेवीएम में चलता है। यदि आपको प्रदर्शन हिट नहीं लगता है (जो हर रोज छोटे हो जाता है)। यह स्वचालित रूप से विधि नामों के आधार पर है। उदाहरण के लिए, '+' 'प्लस (तर्क)' विधि को कॉल करता है।


Sometimes it would be nice to have operator overloading, friend classes and multiple inheritance.

However I still think it was a good decision. If Java would have had operator overloading then we could never be sure of operator meanings without looking through source code. At present that's not necessary. And I think your example of using methods instead of operator overloading is also quite readable. If you want to make things more clear you could always add a comment above hairy statements.

// a = b + c
Complex a, b, c; a = b.add(c);

This is not a good reason to disallow it but a practical one:

People do not always use it responsibly. Look at this example from the Python library scapy:

>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=TCP |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=55 |<TCP |>>

Here is the explanation:

The / operator has been used as a composition operator between two layers. When doing so, the lower layer can have one or more of its defaults fields overloaded according to the upper layer. (You still can give the value you want). A string can be used as a raw layer.







operator-overloading