वापसी के प्रकार स्पष्ट रूप से नहीं दिए जाने पर स्ट्रिंग को वापस करने की विधि को वापस करने की विधि के साथ ओवरराइड क्यों किया जा सकता है?


11

मैं Scala Edition1 में प्रोग्रामिंग में Traits पर अध्याय से कोड उदाहरणों के माध्यम से काम कर रहा था https://www.artima.com/pins1ed/traits.html

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

trait Philosophical {
    def philosophize = println("I consume memory, therefore I am!")
}

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize = "It aint easy to be " + toString + "!"
}

val frog = new Frog
//frog: Frog = green

frog.philosophize
// no message printed on console

val f = frog.philosophize
//f: Unit = ()

लेकिन जब मैं ओवरराइड विधि में स्पष्ट रिटर्न प्रकार देता हूं, तो यह एक संकलित त्रुटि देता है:

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize: String = "It aint easy to be " + toString + "!"
}
         override def philosophize: String = "It aint easy to be " + toString +
                      ^
On line 3: error: incompatible type in overriding
       def philosophize: Unit (defined in trait Philosophical);
        found   : => String
        required: => Unit

क्या कोई यह समझाने में मदद कर सकता है कि पहले मामले में कोई संकलन त्रुटि क्यों नहीं हुई।


कंपाइलर ने एक मान्य संकेत मुद्रित किया है कि आप एक विधि को ओवरराइड करने का प्रयास करते हैं जिसका एक अलग परिणाम प्रकार होता है।
एंड्री प्लक्षोत्तुक 13

हाँ वास्तव में, लेकिन मेरा सवाल यह है कि यह संकलक के माध्यम से 1 मामले में क्यों मिला
शनिल

1
अंगूठे का नियम, हमेशा रिटर्न टाइप_ (विशेष रूप से सार्वजनिक एपीआई पर) _ के बारे में स्पष्ट होना चाहिए। स्थानीय चर के लिए प्रकार का अनुमान बहुत अच्छा है, और कुछ नहीं।
लुइस मिगुएल मेजा सुआरेज़

जवाबों:


8

जब अपेक्षित प्रकार होता है Unit, तो किसी भी मूल्य को स्वीकार किया जा सकता है :

मूल्य में छूट

यदि eकुछ मान प्रकार है और अपेक्षित प्रकार है Unit, eतो इसे टर्म में एम्बेड करके अपेक्षित प्रकार में बदल दिया जाता है { e; () }


6

मेरा सवाल है कि यह 1 मामले में संकलक के माध्यम से क्यों मिला

जब आपने रिटर्न प्रकार स्पष्ट रूप से निर्दिष्ट नहीं किया था तो यह उस प्रकार से अनुमान लगाया गया था जिसे overrideकाम करने के लिए आवश्यक है।

वह निकला Unit

चूंकि Stringमान (फ़ंक्शन बॉडी बनाने वाले अभिव्यक्ति का मूल्य) को सौंपा जा सकता है Unit, संकलक खुश है।


1
हालांकि, अब मैं जानना चाहता हूं कि स्पष्ट रिटर्न प्रकार Stringको अस्वीकार क्यों किया गया। जावा में (और मुझे लगता है कि स्काला में भी), आपको ओवरराइड करते समय रिटर्न प्रकार को संकीर्ण करने की अनुमति है । उदाहरण के लिए, जब मूल विधि वापस आती है Number, तो आप वापस लौट सकते हैं Integer। शायद void/ Unitविशेष है।
थिलो

1
यह संकलन, उदाहरण के लिए:trait Philosophical { def philosophize : Number = 1 } class Frog extends Philosophical { override def philosophize : Integer = 2 }
थिलो

2
आप रिटर्न प्रकार को एक उपप्रकार में संकीर्ण कर सकते हैं; लेकिन आप इसे एक प्रकार तक सीमित नहीं कर सकते हैं, जिसे केवल ओवरराइड विधि की वापसी प्रकार में परिवर्तित किया जा सकता है। Stringकरने के लिए Unitभले ही यह नहीं है, और अधिक एक दूसरे की तरह है वास्तव में है।
अलेक्सई रोमानोव

2
Bytecode स्तर पर या तो कोई संकीर्ण रिटर्न प्रकार नहीं है, वास्तव में दो तरीके हैं Frog: def philosophize : Integerऔर def philosophize : Number। दूसरा वाला वास्तव में Philosophical's पद्धति को ओवरराइड करता है (और पहले वाले को कॉल करता है)। वही निश्चित रूप से void/ कुछ और के लिए किया जा सकता है , डिजाइनरों ने इसे नहीं करने का फैसला किया।
अलेक्सई रोमानोव

2
1. जावा ऐसा ही करता है। 2. हाँ, बाईटेकोड में आप कर सकते हैं। उदाहरण के लिए देखें stackoverflow.com/questions/18655541/… और stackoverflow.com/questions/58065680/…
एलेक्सी रोमानोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.