2012-03-24 25 views
32

मैं एक प्रोग्रामर हूं जिसने कई भाषाओं में प्रोग्राम किया है, दोनों कार्यात्मक और ओओ उन्मुख हैं। मैंने कुछ जावास्क्रिप्ट भी प्रोग्राम किया, लेकिन इसमें कभी भी इस्तेमाल नहीं किया (या इसका उपयोग करना था)।क्या मुझे जावास्क्रिप्ट में बहुरूपता का उपयोग करना चाहिए?

अब, एक शौक प्रोजेक्ट के रूप में, मैं जावा और सी # में लिखे गए कुछ ऐप्स पोर्ट करना चाहता हूं जो अत्यधिक जावास्क्रिप्ट में बहुरूपता का उपयोग करते हैं।

लेकिन एक पहली नज़र मैं 'यह संभव है लेकिन ...' बहुत पढ़ते

तो वहाँ यह करने के लिए एक विकल्प है पर?

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

abstract class Shape{ { printSurface() } ; } 

class Rect : Shape() { printSurface() { print (sideA*sideB}} 

class Circle : Shape() { printSurface() { print { pi*r*r }} 

TheApp { myshapes.iterate(shape s) {s.printSurface() } } 

तो एक क्लासिक बहुरूपी मामला: baseclass से अधिक पुनरावृत्ति।

मैं इस तरह के व्यवहार को प्राप्त करना चाहता हूं। मुझे पता है कि बहुलकवाद है, लेकिन क्या कोई अन्य 'पैटर्न' है जो मुझे लगता है कि इस तरह के व्यवहार को प्राप्त करने के लिए या मुझे जावास्क्रिप्ट में विरासत की संभावनाओं का अध्ययन करना चाहिए?

उत्तर

43

जैसा कि कहा गया है, जावास्क्रिप्ट प्रोटोटाइप विरासत पर आधारित गतिशील टाइप की गई भाषा है, इसलिए आप वास्तव में टाइप की गई भाषाओं के समान दृष्टिकोण का उपयोग नहीं कर सकते हैं।आप क्या लिखा है की एक जे एस संस्करण, हो सकता है:

function Shape(){ 
    throw new Error("Abstract class") 
} 

Shape.prototype.printSurface = function() { 
    throw new Error ("Not implemented"); 
} 

function Rect() { 
    // constructor; 
} 

Rect.prototype = Object.create(Shape.prototype); 
Rect.prototype.printSurface = function() { 
    // Rect implementation 
} 

function Circle() { 
    // constructor; 
} 

Circle.prototype = Object.create(Shape.prototype); 
Circle.prototype.printSurface = function() { 
    // Circle implementation 
} 

फिर, अपने अनुप्रयोग में:

var obj = new Circle(); 

if (obj instanceof Shape) { 
    // do something with a shape object 
} 

या, बतख टाइपिंग के साथ:

if ("printSurface" in obj) 
    obj.printSurface(); 

// or 

if (obj.printSurface) 
    obj.printSurface(); 

// or a more specific check 
if (typeof obj.printSurface === "function") 
    obj.printSurface(); 

तुम भी Shape के रूप में ठंड बिना किसी कन्स्ट्रक्टर के ऑब्जेक्ट, यह अधिक "अमूर्त वर्ग" जैसा है:

var Shape = { 
    printSurface : function() { 
     throw new Error ("Not implemented"); 
    } 
} 

function Rect() { 
    // constructor; 
} 

Rect.prototype = Object.create(Shape); 
Rect.prototype.printSurface = function() { 
    // Rect implementation 
} 

function Circle() { 
    // constructor; 
} 

Circle.prototype = Object.create(Shape); 
Circle.prototype.printSurface = function() { 
    // Circle implementation 
} 

सूचना है कि इस मामले में, आप instanceof अब और उपयोग कर सकते हैं नहीं है, तो या आप बतख टाइपिंग पर वापस आने या आप isPrototypeOf उपयोग करने के लिए है, लेकिन केवल हाल के ब्राउज़रों में उपलब्ध है:

if (Shape.isPrototypeOf(obj)) { 
    // do something with obj 
} 

Object.create में उपलब्ध नहीं है ब्राउज़र जो ईएस 5 चश्मा लागू नहीं करता है, लेकिन आप आसानी से पॉलीफिल का उपयोग कर सकते हैं (लिंक देखें)।

+0

टीएक्स, बहुत अच्छा जवाब। लेकिन व्यावहारिक रूप से, मैं जोस, क्लासफ्रेमवर्क के लिए जाऊंगा। – Peter

+0

यह दस्तावेज़ के लिए काम नहीं करता है। मैं एनएमएल दस्तावेज़ तैयार करना चाहता था जो दस्तावेज़ से विरासत में मिला लेकिन एक अजीब '[LenientThis] 'त्रुटि आई। – m93a

14

यहां खेलने में "पैटर्न" "इंटरफ़ेस" होगा। जब तक myshapes संग्रह में सभी ऑब्जेक्ट्स printSurface() विधि लागू करें, तो आप ठीक होंगे।

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

+1

हाँ घंटी बजती है, अजगर की तरह? – Peter

+1

यहां तक ​​कि वही उदाहरण मैंने उपयोग किया है यहां दिखाया गया है: http://knol.google.com/k/programming-to-the-interface-in-javascript-yes-it-can-be-done-er-i- मतलब-फिकड # – Peter

+1

मुझे नहीं पता कि यह उत्तर अधिक क्यों नहीं है। यह जावास्क्रिप्ट के बारे में सरल सत्य बताता है और यह polymorphism सिर्फ गुणों का नामकरण कर रहा है। चिंता करने के लिए कोई भी प्रकार की बाधा नहीं है। – hayavuk

7

मुझे पता है कि यह प्रोटोटाइप के साथ किया जा सकता है लेकिन मैं इसका उपयोग करने का स्वामी नहीं हूं। i prefer the object literal approach

//shape class 
var shape = function() { 
    //return an object which "shape" represents 
    return { 
     printSurface: function() { 
      alert('blank'); 
     }, 
     toInherit: function() { 
      alert('inherited from shape'); 
     } 
    } 
}; 

//rect class 
var rect = function() { 
    //inherit shape 
    var rectObj = shape(); 

    //private variable 
    var imPrivate = 'Arrr, i have been found by getter!'; 

    //override shape's function 
    rectObj.printSurface = function(msg) { 
     alert('surface of rect is ' + msg); 
    } 

    //you can add functions too 
    rectObj.newfunction = function() { 
     alert('i was added in rect'); 
    } 

    //getters and setters for private stuff work too 
    rectObj.newGetter = function(){ 
     return imPrivate; 
    } 

    //return the object which represents your rectangle 
    return rectObj; 
} 



//new rectangle 
var myrect = rect(); 

//this is the overridden function 
myrect.printSurface('foo'); 

//the appended function 
myrect.newfunction(); 

//inherited function 
myrect.toInherit(); 

//testing the getter 
alert(myrect.newGetter()); 

+0

मुझे बाद में इसमें देखना होगा, लेकिन हमेशा के लिए +1 है ताकि कोडडैमल्स प्रदान करने का प्रयास कौन करता है! – Peter

+1

@Weston: क्या यह एक अलग उत्तर होने के लिए पर्याप्त विषय पर नहीं है? ढांचे पर चर्चा की जा सकती है। अभी के लिए: प्रदर्शन जुर्माना हमेशा स्वीकार्य है? – Peter

4

वेस्टन कहते हैं, अगर आप विरासत के लिए जरूरत इस तरह के एक गतिशील भाषा की तो बतख टाइप प्रकृति की जरूरत नहीं है (कल्पना करने के लिए और एक "निजी" गुंजाइश है आसान) क्योंकि जावास्क्रिप्ट आपको बहुरूपता देता है क्योंकि भाषा में दृढ़ता से टाइप की गई बेस क्लास या इंटरफेस के लिए भाषा में कोई आवश्यकता नहीं है।

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

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

+0

मुझे पता है कि कॉफ़ीस्क्रिप्ट मुझे पता है, लेकिन संकलन चरण मेरे लिए बहुत अधिक है .. – Peter

4

एक और नोट पर। यदि आप कक्षाओं का उपयोग कर ओओ शैली में जावास्क्रिप्ट प्रोग्राम करना चाहते हैं, तो आप जावास्क्रिप्ट के लिए कई "क्लास-सिस्टम" देख सकते हैं। एक उदाहरण जोस (http://joose.it) है।

कई ग्राहक पक्ष ढांचे अपने स्वयं के वर्ग प्रणाली को लागू करते हैं। इसका एक उदाहरण ExtJS है।

+2

अब इसे आजमा रहा है, यह वास्तव में बहुत अच्छा है – Peter

+0

या बस कक्षाओं के बारे में भूल जाओ और वस्तुओं को गले लगाओ। – hayavuk

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