2016-04-20 6 views
11

मैं स्कैला के संदर्भ में मिक्सिन को समझने की कोशिश कर रहा हूं। विशेष रूप से मैं विरासत और मिक्सिन की अवधारणाओं के बीच अंतर जानना चाहता था। विकी का कहना है कि मिश्रण और विरासत की अवधारणाओं के बीच महत्वपूर्ण अंतर है और इसलिए मैं इसे समझना चाहता था।मिश्रण और विरासत के बीच क्या अंतर है?

wiki में Mixin की परिभाषा का कहना है:

एक मूल वर्ग के रूप में mixin वर्ग में कार्य करता है, वांछित कार्यशीलता हैं। एक सबक्लास तब इस कार्यक्षमता का उत्तराधिकारी या पुन: उपयोग कर सकता है, लेकिन विशेषज्ञता के साधन के रूप में नहीं। आम तौर पर, मिश्रित एक कठोर, एकल "एक" संबंध बनाने के बिना, वांछित कार्यक्षमता को बाल वर्ग में निर्यात करेगा। यहां मिश्रित और विरासत की अवधारणाओं के बीच महत्वपूर्ण अंतर है, जिसमें बाल वर्ग अभी भी मूल वर्ग की सभी विशेषताओं का उत्तराधिकारी हो सकता है, लेकिन बच्चे के बारे में अर्थशास्त्र "माता-पिता होने के बारे में" आवश्यक रूप से लागू नहीं होना चाहिए

उपर्युक्त परिभाषा में, मैं बोल्ड में चिह्नित बयानों को समझने में सक्षम नहीं हूं। इसका क्या मतलब है कि

  1. एक उपवर्ग नहीं बल्कि विशेषज्ञता
  2. mixins में के साधन के रूप mixin में कार्यक्षमता के वारिस कर सकते हैं, बच्चे बच्चे के बारे में माता पिता के वर्ग की सभी सुविधाओं लेकिन अर्थ विज्ञान "एक प्रकार जा रहा है" विरासत माता-पिता को जरूरी नहीं जरूरी है। - एक बच्चा माता-पिता को कैसे बढ़ा सकता है और जरूरी नहीं कि एक तरह का अभिभावक? क्या ऐसा कोई उदाहरण है।

उपर्युक्त के बारे में किसी भी स्पष्टीकरण के लिए अग्रिम धन्यवाद।

+0

स्कैला में, मिक्सिन को एक साफ संकलन-समय परिवर्तन के रूप में सोचें जो कुछ प्रकारों को अतिरिक्त तरीकों से सजाएगा। इस मामले में, जबकि स्कैला प्रकार चेकर के लिए "मिश्रित प्रकारों" का ट्रैक रखता है, विधि परिभाषाएं स्वयं * वास्तविक प्रकारों में * चपटा * होती हैं, इसलिए JVM कक्षाओं में कोई अभिभावक-बच्चा स्थापित नहीं होता है। विरासत आमतौर पर रनटाइम पॉलीमोर्फिक विधि संकल्प से जुड़ा होता है - लेकिन मिक्स्ड (बड़े पैमाने पर) ऑर्थोगोनल अवधारणाएं हैं। जावा 8 इंटरफ़ेस डिफ़ॉल्ट तरीके मिश्रित भी हैं। – user2864740

+0

ऐसा लगता है कि [व्यापक संदर्भ में पहले पूछा गया था] (http://stackoverflow.com/questions/860245/mixin-vs-inheritance) (हालांकि मैं वहां उत्तरों से पूरी तरह संतुष्ट नहीं हूं)। – badcook

उत्तर

7

मुझे यकीन नहीं है कि मैं आपके प्रश्न को सही तरीके से समझ गया हूं, लेकिन अगर मैंने किया, तो आप पूछ रहे हैं कि विरासत के समान चीज़ के बिना वास्तव में कुछ कैसे प्राप्त किया जा सकता है।

हालांकि, मिक्सिन विरासत नहीं हैं - यह वास्तव में गतिशील रूप से किसी ऑब्जेक्ट में विधियों का एक सेट जोड़ना समान है। जबकि विरासत कहती है "यह बात एक और चीज है", मिक्सिन कहते हैं, "इस वस्तु के इस अन्य चीज़ के कुछ लक्षण हैं।" आप इसे मिक्सिन घोषित करने के लिए इस्तेमाल किए गए कीवर्ड में देख सकते हैं: trait

टूक स्काला मुखपृष्ठ से एक उदाहरण चोरी करने के लिए:

abstract class Spacecraft { 
    def engage(): Unit 
} 
trait CommandoBridge extends Spacecraft { 
    def engage(): Unit = { 
    for (_ <- 1 to 3) 
     speedUp() 
    } 
    def speedUp(): Unit 
} 
trait PulseEngine extends Spacecraft { 
    val maxPulse: Int 
    var currentPulse: Int = 0 
    def speedUp(): Unit = { 
    if (currentPulse < maxPulse) 
     currentPulse += 1 
    } 
} 
class StarCruiser extends Spacecraft 
        with CommandoBridge 
        with PulseEngine { 
    val maxPulse = 200 
} 

इस मामले में, StarCruiser एक CommandoBridge या PulseEngine नहीं है; यह में है, हालांकि, और उन लक्षणों में परिभाषित विधियों को प्राप्त करते हैं। यह Spacecraft है, जैसा कि आप देख सकते हैं क्योंकि यह उस वर्ग से प्राप्त होता है।

यह उल्लेखनीय है कि traitclass बढ़ाता है, यदि आप with कुछ विशेषता बनाना चाहते हैं, तो उसे उस वर्ग को विस्तारित करना होगा। उदाहरण के लिए, यदि मेरे पास class Dog था, तो मेरे पास Dog with PulseEngine नहीं हो सका जब तक Dog विस्तारित Spacecraft। इस तरह, यह विधियों को जोड़ने की तरह नहीं है; हालांकि, यह अभी भी समान है।

1

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

2

एक विशेषता (जो mixin जब एक वर्ग के साथ मिश्रित कहा जाता है) जावा में एक अंतरफलक की तरह है (कई देखते हैं, हालांकि differences) आप जरूरी बिना एक वर्ग के लिए अतिरिक्त सुविधाओं को जोड़ सकते हैं, जहां "एक" रिश्ते। या आप कह सकते हैं कि आम तौर पर लक्षण बंडल अप सुविधाओं का उपयोग करते हैं जिनका उपयोग कई स्वतंत्र वर्गों द्वारा किया जा सकता है।

आप वर्गों प्राकृतिक आदेश के साथ डेटा हो सकता है के लिए स्काला पुस्तकालय से एक उदाहरण देने के लिए, Ordered[A] एक trait जो कुछ बुनियादी तुलना संचालन के लिए कार्यान्वयन प्रदान करता है (जैसे <, <=, >, >=)।

उदाहरण के लिए, मान लें कि आपके पास अपनी खुद की कक्षा Number है और उपरोक्त EvenNumber और OddNumber जैसा नीचे दिखाया गया है।

class Number(val num : Int) extends Ordered[Number] { 
    override def compare(that : Number) = this.num - that.num 
} 

trait Half extends Number { 
    def half() = num/2 
} 

trait Increment extends Number { 
    def increment() = num + 1 
} 

class EvenNumber(val evenNum : Int) extends Number(evenNum) with Half 

class OddNumber(val oddNum : Int) extends Number(oddNum) with Increment 

उपरोक्त उदाहरण में, कक्षाओं EvenNumber और OddNumber शेयर Number लेकिन EvenNumber के साथ एक संबंध नहीं है है के साथ HalfOddNumber शेयर संबंध "एक" Increment साथ संबंध "एक है।"

एक और महत्वपूर्ण बात यह है भले ही वर्ग Numberextends Ordered सिंटैक्स का उपयोग करता है, इसका मतलब Number एक निहितOrdered यानी Any की सुपर क्लास के साथ एक रिश्ता है किया है।

2

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

स्कैला में एक विशेषता कार्यान्वयन कर सकती है और यह उन्हें विस्तारित करने और उनका उपयोग करने के लिए प्रेरित है।

विरासत विरासत के लिए उपयोग किया जा सकता है। इसे मिक्सेस भी कहा जा सकता है हालांकि मेरी राय में mixin व्यवहार का उपयोग करने का सबसे अच्छा तरीका नहीं है। इस मामले में आप जावा सार कक्षाओं के रूप में लक्षणों के बारे में सोच सकते हैं। जिसमें आपको उप-वर्ग मिलते हैं जो सुपर क्लास (विशेषता) के "प्रकार" होते हैं।

हालांकि लक्षणों का उपयोग proper mixins के रूप में भी किया जा सकता है। अब mixin के रूप में एक विशेषता का उपयोग करके कार्यान्वयन पर निर्भर करता है कि "आप इसे कैसे मिलाएं"। ज्यादातर अपने आप से पूछने के लिए एक सरल सवाल है। यह है "क्या विशेषता के उप-वर्ग वास्तव में kind विशेषता के हैं या बॉयलरप्लेट को कम करने वाले लक्षण व्यवहार में व्यवहार हैं"। आमतौर पर यह सर्वोत्तम वर्गों को बनाने के लिए विशेषता को विस्तारित करने के बजाय वस्तुओं में लक्षणों में मिश्रण करके सर्वोत्तम रूप से कार्यान्वित किया जाता है।

उदाहरण के लिए निम्नलिखित उदाहरण पर विचार करें: - यह विरासत है

val wiredObject = new service with concreteDAO -

//All future versions of DAO will extend this 
trait AbstractDAO{ 
    def getRecords:String 
    def updateRecords(records:String):Unit 
} 
//One concrete version 
trait concreteDAO extends AbstractDAO{ 
    override def getRecords={"Here are records"} 
    override def updateRecords(records:String){ 
    println("Updated "+records) 
    } 
} 
//One concrete version 
trait concreteDAO1 extends AbstractDAO{ 
    override def getRecords={"Records returned from DAO2"} 
    override def updateRecords(records:String){ 
    println("Updated via DAO2"+records) 
    } 
} 
//This trait just defines dependencies (in this case an instance of AbstractDAO) and defines operations based over that 
trait service{ 
    this:AbstractDAO => 

    def updateRecordsViaDAO(record:String)={ 
    updateRecords(record) 
    } 
    def getRecordsViaDAO={ 
    getRecords 
    } 
} 


object DI extends App{ 
    val wiredObject = new service with concreteDAO //injecting concrete DAO to the service and calling methods 
    wiredObject.updateRecords("RECORD1") 
    println(wiredObject.getRecords) 

    val wiredObject1 = new service with concreteDAO1 
    wiredObject1.updateRecords("RECORD2") 
    println(wiredObject1.getRecords) 

} 

concreteDAO एक विशेषता है जो AbstractDAO फैली हुई है यह उचित mixin व्यवहार सेवा विशेषता के बाद से की mixin जनादेश है एक AbstractDAOService के लिए ConcreteDAO को विस्तारित करने के लिए यह गलत होगा क्योंकि service आवश्यक AbstractDAO यह AbstractDAO का प्रकार नहीं है। इसके बजाय आप विभिन्न मिश्रणों के साथ service के उदाहरण बनाते हैं।

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