2012-10-01 11 views
19

पर इंटरफ़ेस बढ़ाएं मेरे पास एक इंटरफ़ेस (चाल) है जो कुछ आकारों को ले जाना चाहिए।एक अमूर्त वर्ग

interface Move { move(); } 
abstract class Shape : Move 

class Circle : Shape 
class Square : Shape 
class Triangle : Shape 

मेरे संदेह नहीं है, मैं एक अंतरफलक जो आकृतियाँ लेकिन केवल सर्किल और त्रिभुज स्थानांतरित करने में सक्षम होना चाहिए चाल होना आवश्यक है, तो मैं कैसे स्क्वायर से इंटरफेस "निकालें" करते हैं? क्या मुझे आकार से इंटरफ़ेस को हटा देना चाहिए और इसे मंडल और त्रिकोण पर मैन्युअल रूप से जोड़ना चाहिए? मैं इसके साथ उलझन में हूँ। उम्मीद है कि कोई मेरी मदद कर सकता है।

उत्तर

34

आप सेटअप करना चाहिए इस तरह अपनी कक्षाओं:

interface IMovable { move(); } 
abstract class Shape : { } 

class Circle : Shape, IMovable { } 
class Square : Shape { } 
class Triangle : Shape, IMovable { } 

नहीं हर आकार ले जाया जा सकता है, तो Shape इंटरफ़ेस को लागू नहीं करना चाहिए। यह भी ध्यान दें कि मैंने आपके इंटरफ़ेस को IMovable पर बदल दिया है, यह एक बड़ा सौदा नहीं है लेकिन यह अधिक स्वीकार्य और बेहतर नामकरण सम्मेलन है।

+4

यह। प्रश्न का उत्तर "मैं कुछ आधार व्यवहार को कैसे प्राप्त नहीं कर सकता" हमेशा "पहले स्थान पर इसका उत्तराधिकारी नहीं है"। – KeithS

+0

@ किथ्स, यह सही है। विरासत को रोकना विरासत को देखने का एक विपरीत तरीका है। तो, उम्मीद है कि इससे ओपी को दूसरी तरफ आगे बढ़ने में मदद मिलेगी। :) –

+4

@ माइक, 'IMovable' के बारे में कैसे? – smartcaveman

27

आप विरासत के पेड़ से एक इंटरफ़ेस नहीं हटा सकते हैं।

आपको मॉडल को दो अमूर्त वर्गों की आवश्यकता होती है - Shape और MovableShape

interface IMove { move(); } 
abstract class Shape : {} 
abstract class MovableShape : IMove, Shape {} 

class Circle : MovableShape{} 
class Square : Shape{} 
class Triangle : MovableShape{} 
+3

यह स्वीकार्य उत्तर होना चाहिए। –

+3

@ नदिरसंपोली, आप __opinion__ को उचित रूप से नोट किया गया है, लेकिन सावधान रहें क्योंकि यह एक बहुत ही व्यक्तिपरक वार्तालाप में बदल जाएगा। ध्यान देने योग्य एक बात यह है कि __ मैंने इस उत्तर को भी +1 किया क्योंकि यह काफी सही है। –

+3

@ माइक मैं क्षमा चाहता हूं, वास्तव में मेरी टिप्पणी बोल्ड लगता है; मुझे "मेरी राय में" जोड़ना चाहिए था। –

3

आप खुद अंतरफलक, क्लासों, OO के पीछे एक विचार सामान्य रूप में से परिचित करना चाहिए। जो आप बताने की कोशिश कर रहे हैं वह निम्नलिखित है:

  • प्रत्येक आकार को स्थानांतरित किया जा सकता है।
  • एक स्क्वायर एक आकार है।
  • लेकिन एक स्क्वायर स्थानांतरित नहीं किया जा सकता है।

स्पष्ट रूप से यह समझ में नहीं आता है। तो आपको अपने वर्ग के डिजाइन को समायोजित करना होगा। या तो प्रत्येक आकार को स्थानांतरित किया जा सकता है, कि आकार (और स्क्वायर) को कार्यान्वित करना चाहिए, या हर आकार को स्थानांतरित नहीं किया जा सकता है, तो आकार को मूव लागू नहीं करना चाहिए।

3

इस आजमाएं:

interface IMove { move(); } 
abstract class Shape { } 

class Circle : Shape, IMove { } 
class Square : Shape { } 
class Triangle : Shape, IMove { } 
2

अन्य विकल्प सिर्फ Shape कक्षा में IMove.Move विधि को लागू किया जा सकता है और डिफ़ॉल्ट रूप से एक NotSupportedException फेंक देते हैं।

public abstract class Shape : IMove 
{ 
    public virtual void Move() 
    { 
     throw new NotSupportedException(); 
    } 
} 

तो दिन के अंत में, "किसी भी आकार चल हो सकता है" लेकिन "एक चल आकार यह कैसे ले जाने के लिए के अपने स्वयं के कार्यान्वयन प्रदान करना चाहिए"।

अंत में, आइए कल्पना करें कि आकारों का एक समूह है जो उसी तरह से स्थानांतरित हो जाते हैं। आप DefaultMovableShape अमूर्त वर्ग Shape प्राप्त करने वाले सार वर्ग बनाएंगे, जो Shape.Move आभासी विधि को ओवरराइड करता है।

public abstract class DefaultMovableShape 
{ 
    public override void Move() 
    { 
      // Do stuff 
    } 
} 
+0

हालांकि यह काम करता है, मैं इसके खिलाफ सलाह दूंगा जब तक कि 'मूव' फ़ंक्शन के लिए आपका स्पेस स्पष्ट रूप से इंटरफ़ेस परत पर बताता है कि 'मूव' मामले में अपवाद फेंक सकता है, यह अंतर्निहित ऑब्जेक्ट के लिए लागू नहीं है। बेशक, उस बिंदु पर आपको सवाल होना चाहिए कि यह इंटरफ़ेस को क्यों लागू करता है और आपके पास शायद एक डिज़ाइन समस्या है (स्वीकृत उत्तर देखें)। – Anthony

+0

@ एंथनी मैं सहमत हूं। मैं बस एक विकल्प देना चाहता था। मेरा मानना ​​है कि ऐसा सोचने के कारण हैं कि स्वीकार्य उत्तर ऐसा करने का सही तरीका है, लेकिन कुछ भी स्थिति में, मेरा काम भी हो सकता है। यह इस बात पर निर्भर करता है कि आप समस्या को कैसे सोचते हैं: "एक आकार जंगम नहीं है" या "एक आकार चल सकता है"। –

+0

@ एंथनी मैंने आपकी टिप्पणी को दोबारा जांच लिया है। यह कथन 'आकार 'वर्ग दस्तावेज में होना चाहिए और न ही' IMove' होना चाहिए। आकार "स्थानांतरित हो सकता है" क्योंकि एक आकार "कैसे स्थानांतरित करें" के कार्यान्वयन प्रदान कर सकता है। तो यदि आप एक ऐसे आकार को स्थानांतरित करने की कोशिश कर रहे हैं जिसे स्थानांतरित नहीं किया जा सकता है, तो यह आकार "चलने का समर्थन नहीं करता"। –

2

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

आप इन वर्गों का उपयोग और विस्तार करने की अपेक्षा कैसे करते हैं, यह भी महत्वपूर्ण है। क्या आप भविष्य में 'स्क्वायर' को चलने की आवश्यकता होगी?क्या एक आकार की गतिशीलता हमेशा स्थैतिक है, या यह गतिशील विशेषता के रूप में अधिक उपयोगी हो सकती है? क्या मूव() के पास कक्षाओं के लिए कोई मूल्य है जो आकार नहीं हैं? जंगमता एक गतिशील विशेषता के रूप में उपयोगी हो सकता है, तो यह विचार करें:

public abstract class Shape 
{ 
    public bool isMovable() 
    { 
     return false; 
    } 

    public virtual void Move() 
    { 
     if (!isMovable() { 
      throw new NotSupportedException(); 
     } else { 
      throw new BadSubclassException(); 
     } 
    } 
} 

आपका उपवर्गों तो या तो स्थिर या गतिशील व्यवहार प्रदान करने के लिए isMovable ओवरराइड कर सकते हैं, और आगे संशोधित किया जा सकता या समय के साथ subclassed, इतने लंबे समय के अपने दस्तावेज़ में आता है के रूप में स्पष्ट करें कि चलने योग्य को हमेशा कॉल करने के लिए कॉल से पहले होना चाहिए। डिफ़ॉल्ट व्यवहार उन लोगों की अपेक्षाओं पर आधारित होना चाहिए जिन्हें आप अपने कोड का उपयोग करने की अपेक्षा करते हैं, इस आधार पर कि उन्होंने संबंधित डिज़ाइन पैटर्न कैसे कार्यान्वित किए हैं।

इन निर्णयों को बनाने की चुनौती का एक अच्छा उदाहरण विभिन्न ढांचे में संग्रह वर्गों की उत्परिवर्तन विकसित करने के इतिहास को देखकर पाया जा सकता है। वहां ऐसे डिज़ाइन किए गए हैं जहां म्यूटेबल क्लासेस (सेट, एरे, डिक्शनरी इत्यादि) बेस क्लास रहे हैं, जिसमें सबक्लास में लागू अपरिवर्तनीयता के साथ-साथ रिवर्स भी शामिल है। दोनों दृष्टिकोणों के साथ-साथ एक गतिशील दृष्टिकोण के लिए वैध तर्क हैं, लेकिन ढांचे के उपयोगकर्ता के लिए सबसे महत्वपूर्ण कारक स्थिरता, क्योंकि सही क्या है वास्तव में उपयोग करने के लिए सबसे आसान क्या है, सुरक्षा प्रदान करना और प्रदर्शन समझौता नहीं किया गया है।

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