2011-04-08 15 views
9

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

मैं इंजन को ईंधन भरने के लिए एक विधि बनाना चाहता हूं। क्या मुझे इसे बेस क्लास स्तर पर एक अमूर्त विधि के रूप में करना चाहिए और इसे एक सामान्य फेशन में नाम देना चाहिए, जैसे fillUpEnergy?

समस्या यह है कि यदि मेरे पास इलेक्ट्रिक इंजन है, तो विधि के पैरामीटर की संख्या ईंधन इंजन के लिए पारित होने वाले पैरामीटर की संख्या से अलग होती है। तो, विधि का हस्ताक्षर अलग है।

इसके अलावा, क्या दोनों इंजनों के लिए जेनेरिक विधि का उपयोग करने के लिए कोई आसान तरीका है लेकिन इसे अधिक विशिष्ट नाम में लपेटना है? उदाहरण के लिए: एक ईंधन इंजन के लिए, "refuel", और एक इलेक्ट्रिक इंजन के लिए, "चार्ज बैटरी"? और साथ ही उपयोगकर्ता से जेनेरिक विधि छुपाएं?

+0

इलेक्ट्रिक और ईंधन इंजन के लिए रिफाइवल के लिए कोई सामान्य पैरामीटर हैं? – tomasmcguinness

उत्तर

2

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

2

आपके पास एक इंटरफेस लेने वाले ईंधन भरने का तरीका हो सकता है?

eg 
public void Refuel(IFuel fuel) 
{ 
//do refueling logic 
} 

आपके दो प्रकार के ईंधन भरने वाले पैरामीटर क्या करते हैं?

+0

यह चालाक है। यह देखना बहुत दिलचस्प होगा कि IFuel को सामान्य रूप से कैसे उपयोग किया जा सकता है। – n8wrl

+0

इस बात पर निर्भर करता है कि अन्य दो तरीकों से कौन से पैरामीटर होंगे, यह संभव हो सकता है।IFuel इंटरफ़ेस में एक विधि हो सकती है जो ईंधन की मात्रा के लिए एक दशमलव देता है उदाहरण के लिए – WraithNath

+0

हाँ। मैं सोच रहा था कि अगर 'ईंधन' में कोई भी नहीं फैलता है या बारिश में नहीं कर रहा है तो यह अभी भी इंजन-प्रकार-आश है। – n8wrl

5

इस स्थिति में, मैं अपने सार वर्ग के एक सामान्य कार्यान्वयन को परिभाषित करेगा, इस तरह है कि आप कुछ इस तरह मिलती है: वैकल्पिक रूप से

public class ElectricEngine : EngineBase<ElectricParameters> 
{ 
    public override void Refuel(ElectricParameters parameters) { } 
} 

: तो फिर अपने कार्यान्वयन इस तरह दिखना

public abstract class EngineBase<T> 
{ 
    public abstract void Refuel(T parameters); 
} 

, आप एक इंटरफेस को परिभाषित कर सकते हैं, और अपने तरीकों के लिए एक विशिष्ट कार्यान्वयन पास कर सकते हैं:

public abstract class EngineBase 
{ 
    public abstract void Refuel(IRefuelParameters parameters); 
} 

फिर अपने कार्यान्वयन इस तरह दिखेगा:

public class ElectricEngine : EngineBase 
{ 
    public override void Refuel(IRefuelParameters parameters) 
    { 
      if(!(parameters is ElectricParameters)) 
       throw ApplicationException("Not the right params!"); 

      ElectricParameters rightParams = parameters as ElectricParameters; 
    } 
} 
+0

जबकि पहला समाधान सीधे पैरामीटर के साथ समस्या हल करता है, यह आधार वर्ग बेकार बनाता है। इंटरफ़ेस समाधान बहुत बेहतर है। – siride

0

मैं इंजन और ईधन करने योग्य/रिचार्जेबल भागों को अलग होगा। या आपको इंजन से संबंधित सभी चीजों को सामान्यीकृत करना होगा। उदाहरण के लिए, आप एक और सार प्रकार (या इंटरफ़ेस) Charge बना सकते हैं, और इसे recharge विधि (जिसे मूल सार Engine कक्षा में परिभाषित किया गया है) में पास कर सकते हैं। अगर आपको कुछ कोड चाहिए तो मुझे बताएं।

+0

बस उन पंक्तियों के साथ कुछ टाइप कर रहा था। मैं एक TorqueProducer के बारे में सोच रहा था जो एक PowerSource तर्क लेता है। –

-1

एक अमूर्त वर्ग वास्तव में उचित नहीं है क्योंकि Refuel एक फ़ंक्शन (विधि) नहीं है जो पैरामीटर के रूप में एक योग प्रकार लेता है।

इस तरह कुछ कैसे?

interface IEngine 
{ 
    void Refuel(FuelingStation station);   
} 

class FuelingStation 
{ 
    double Gas; 
    double Air; 
    double Charge; 


    private double GetFuel(ref double fuel, double requested) 
    { 
     var temp = Math.Max (0, fuel - requested); 

     fuel -= temp; 

     return temp; 
    } 


    public double GetGas(double requestedAmount) 
    { 
     return GetFuel (ref Gas, requestedAmount); 

    } 

    public double GetAir(double requestedAmount) 
    { 
     return GetFuel (ref Air, requestedAmount); 
    } 

    public double GetCharge(double requestedAmount) 
    { 
     return GetFuel (ref Charge, requestedAmount); 
    } 
} 


class GasEngine : IEngine 
{ 

    double Tank; 
    double Capacity; 


    public void Refuel(FuelingStation station) 
    { 
     Tank = station.GetGas (Capacity - Tank); 
    } 
} 


class Electric : IEngine 
{ 

    double Charge; 
    double ChargeCapacity; 

    double Tank; 
    double TankCapacity; 



    public void Refuel(FuelingStation station) 
    { 
     Tank = station.GetGas (TankCapacity - Tank); 
     Charge = station.GetCharge (ChargeCapacity - Charge); 
    } 
} 
संबंधित मुद्दे