2013-02-12 24 views
5

मेरे पास ऑब्जेक्ट्स की एक सूची है जो बेस क्लास से बढ़ती है। अब मैं केवल सूची में कक्षाओं के एक उदाहरण पर एक विशिष्ट संचालन लागू करना चाहता हूं।उदाहरण के लिए एक अच्छा अभ्यास है?

क्या instanceof का उपयोग एक अच्छा अभ्यास है? या मुझे वस्तुओं को अलग करना चाहिए जैसे कि कस्टम enum?

abstract class Base; 
class Foo extends Base; 
class Bar extends Base; 

List<Base> bases; 

for (Base base : bases) { 
    if (base instanceof Bar.class) { 
    //execute my custom operation on the base object 
    doSomething((Bar) base); 
    } 
} 

यदि यह दृष्टिकोण सामान्य रूप से अच्छा नहीं है, तो मैं बेहतर कैसे कर सकता हूं?

+6

पॉलिमॉर्फिज्म का उपयोग करें; यही कारण है कि यह मौजूद है। –

+0

बिल्कुल - करने के बजाय कुछ (बेस) - आपको कुछ आधार लागू करना चाहिए। कुछ(), जो foo.do कुछ() में ओवरराइड है। Google polymorphism जावा - या - ओवरराइड विधि जावा। –

+3

मुझे यह विशेष उत्तर पसंद है: http://www.javapractices.com/topic/TopicAction.do?Id=31। मुझे एहसास है कि सी ++ और जावा अलग हैं लेकिन ** "जब भी आप स्वयं को फॉर्म के कोड लिखते हैं", यदि ऑब्जेक्ट टी 1 प्रकार है, तो कुछ करें, लेकिन यदि यह टी 2 टाइप है, तो कुछ और करें, "खुद को थप्पड़ मारो। * * – thang

उत्तर

3

वास्तव में यहां उदाहरण का उपयोग करने का कोई कारण नहीं है। यह समझ सकता है कि बेस क्लास कुछ भी करने के लिए व्यवहार को डिफ़ॉल्ट नहीं करता है और आवश्यकता होने पर कक्षाओं को विस्तारित करने में इसे ओवरराइड करता है। इस तरह यदि आप आवश्यक हो तो केवल इसे ओवरराइड करें (मैंने इसे इस सारणी के साथ अनुशंसित करने के लिए एक अमूर्त वर्ग के रूप में छोड़ा है)। उदाहरण के लिए:

abstract class Base{ 
    public void doSomething(){} 
} 

public class B0 extends Base{ 
    @Override 
    public void doSomething(){//actually do something} 
} 

public class B1 extends Base{} 

कुछ इस तरह का उपयोग कर किया जा सकता है का एक उदाहरण:

public class SomeOtherClass{ 
    public void something(List<Base> bases){ 
     for(Base base:bases) 
      base.doSomething(); 
    } 
} 
+0

यह एक बहुत अच्छा विचार है क्योंकि मैं कक्षाओं पर कार्यान्वयन छोड़ सकता हूं जो कि उस विधि कॉल पर कुछ भी नहीं करना चाहिए। – membersound

2
abstract class Base;//abstract function doSomething() 
class Foo extends Base;//implements doSomething() 
class Bar extends Base;//dito 

List<Base> bases; 

for (Base base : bases) { 
    base.doSomething(); 
} 

आपके प्रश्न का उत्तर करने के लिए: यह एक अच्छा विचार instanceof उपयोग करने के लिए नहीं है।

+3

अब आप उदाहरण के लिए क्यों जांच रहे हैं .. आपको – smk

+2

गलत वाक्यविन्यास नहीं होना चाहिए, यह "मूल उदाहरण" बार होना चाहिए " – shuangwhywhy

+0

उदाहरण का उपयोग क्यों कर रहे हैं जब यह एक अच्छा विचार नहीं माना जाता है ?? – membersound

1

यहाँ एक अच्छा अभ्यास नहीं है के उदाहरण।

सही समाधान उस doSomething विधि के अंदर वास्तव में क्या चल रहा है इस पर निर्भर करेगा। यदि आप इसे अपने तरीके से करते हैं, तो अन्य चीजों के अलावा, आप Liskov Substitution Principle का उल्लंघन करते हैं। मुझे लगता है कि आपने फैसला किया है कि आपको कुछ कारणों से पहले पदानुक्रम की आवश्यकता है और मैं यह भी मानता हूं कि उपप्रकारों में कुछ और व्यवहार करने की अपेक्षा कुछ और व्यवहार है। इस मामले में, आप क्या कर सकते हैं नीचे दिखाया गया है। असल में केवल प्रकार जो doSomething वास्तव में ऐसा करते हैं और शेष प्रकार no operation जैसे कुछ करते हैं। इस तरह आप यह जानने के बिना इन वस्तुओं का उपयोग कर सकते हैं कि वे वास्तव में किस प्रकार हैं।

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

public abstract class Base 
{ 
    public abstract void doSomething(); 

    public void someOtherMethod() 
    { 
     // which does stuff 
    } 
} 

public class SubTypeWhichCanDoSomething extends Base 
{ 
    @Override 
    public void doSomething() 
    { 
     // actually implement method and DO something 
    } 
} 

public class DoesNothing extends Base 
{ 
    @Override 
    public void doSomething() 
    { 
     // does nothing 
     return; 
    } 
} 

// then your code looks like these 
for(Base base : bases) 
{ 
    base.doSomething(); 
}