2012-11-14 21 views
27
मैंने सोचा था कि

एकाधिक वंशानुक्रम जावा में हमेशा गैरकानूनी था इंटरफेस है, लेकिन इस कोड को संकलित करता है: एक खाली इंटरफेस होनेजावा पर एकाधिक वंशानुक्रम

public interface A { 
    void a(); 
} 

public interface B { 
    void b(); 
} 

public interface AB extends A, B { 
} 

होंगे, जैसे AB एक बुरा व्यवहार पर विचार किया? क्या खाली इंटरफ़ेस से बचने के दौरान कुछ समान हासिल करने का कोई तरीका है (जेनेरिक या अन्यथा उपयोग करके)?

नोट: मैं इंटरफेस के माध्यम से एकाधिक विरासत को अनुकरण करने के लिए नहीं कह रहा हूं। मुझे लगता है मैं निम्नलिखित कर सकता है:

public class AbImpl implements A, B { 
    public void a() {} 
    public void b() {} 
} 

विभिन्न कारणों के लिए मैं एक अंतरफलक दोनों तरीकों है कि जरूरत है।

+0

आपका पहला उदाहरण के लिए एक शॉर्टकट है कि मूल रूप से दूसरे उदाहरण के बराबर है प्रदान करता है। ऐसा करने में कुछ भी गलत नहीं है। –

उत्तर

25

कार्यान्वयन की एकाधिक विरासत की अनुमति नहीं है। हालांकि, घटक कई इंटरफेस का वारिस कर सकते हैं।

एकाधिक इंटरफेस को विरासत में समस्याग्रस्त नहीं है, क्योंकि आप बस लागू करने के लिए नए विधि हस्ताक्षर परिभाषित कर रहे हैं। यह कार्यक्षमता की कई प्रतियों का विरासत है जिसे पारंपरिक रूप से समस्याओं का कारण बनता है, या कम से कम, भ्रम (उदाहरण के लिए, diamond of death)।

+0

डीट के हीरे का जिक्र करने के लिए धन्यवाद;) – servatj

8

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

4

इंटरफेस लागू करना "विरासत" नहीं है, जो तब होता है जब आप कक्षा को बढ़ाते हैं।

कार्यान्वयन इंटरफ़ेस का उपयोग यह घोषित करने के लिए किया जाता है कि एक वर्ग "जैसा दिखता है", जबकि कक्षाओं का विस्तार करने के लिए कक्षा को "एक" कुछ घोषित करने के लिए उपयोग किया जाता है।

एकाधिक चीजों को "जैसा दिखना" ठीक है, लेकिन कई चीजें नहीं बनें।


खाली इंटरफेस है कि एक व्यापक संप्रेषित करने के लिए एक ही इंटरफ़ेस में इंटरफेस का एक सेट का संग्रह करने का एक तरीका के रूप में कई इंटरफेस का विस्तार होने के साथ कुछ भी गलत नहीं है, लेकिन पुन: उपयोग, एपीआई नहीं है।

0

this related question में, जय इसका उत्तर प्रदान करता है। अंतर इंटरफेस बनाम कार्यान्वयन को निर्दिष्ट कर रहा है।

कार्यान्वयन के साथ समस्या तब होती है जब दो कार्यों का एक ही नाम होता है। ऐसा इसलिए है क्योंकि प्रश्न के लिए कोई स्पष्ट विकल्प नहीं है "मैं किस प्रकार का कार्यान्वयन करता हूं?" कई कार्यान्वयन के साथ।

समस्या समान फ़ंक्शन नाम के दो इंटरफेस के साथ नहीं होती है क्योंकि इसे इस चयन को करने की आवश्यकता नहीं है। इसके बजाय, आपको केवल फ़ंक्शन के अपने संस्करण को लागू करने की आवश्यकता है।

उदाहरण के तौर पर, हम does allow multiple inheritance - C++ पर एक समकक्ष को देख सकते हैं। यह लिंक चीजों को अच्छी तरह से बताता है, और कुछ कोड/छवि उदाहरण प्रदान करता है। ध्यान देने योग्य एक बात यह है कि चूंकि आपको स्पष्ट रूप से यह स्पष्ट करने की आवश्यकता है कि किसी भी कार्य में किसी भी प्रकार का कार्य किस प्रकार से संबंधित है, आप सी ++ में इस मुद्दे को आसानी से कम कर सकते हैं।

जावा में हालांकि, हमें वास्तव में ऐसा करने की ज़रूरत नहीं है (क्योंकि केवल वही विधियां हैं जो ऑब्जेक्ट्स से जुड़ी हैं, यदि आप चाहें), परिणामस्वरूप कॉल को गुंजाइश करने की कोई विधि नहीं है। माता-पिता वर्ग को संदर्भित करने के लिए हमें केवल एक ही विकल्प super कीवर्ड का उपयोग करके या static फ़ंक्शन का उपयोग करके किया जाता है। नतीजतन, जावा में इसे हल करने के लिए कोई स्पष्ट विकल्प नहीं होगा, सिस्टम में अतिरिक्त परिवर्तन को छोड़कर, थोड़ा लाभ प्राप्त होगा।

0

इस प्रयास करें, यह जावा 8.

की आवश्यकता है बस कॉपी और Stateful.java में फ़ाइल सहेजें।

यह उपलब्ध यहाँ भी है: https://bitbucket.org/momomo/opensource/src/e699d8da450897b5f6cd94a5d329b3829282d1d6/src/momomo/com/Stateful/Stateful.java?at=default

/************************************************************************************************************************************** 
* Copyright(C) 2014, Mo Enterprises Inc.                        * 
* All rights reserved.                            * 
* Mo Enterprises Inc Opensource License 'MoL1'.                      * 
*                                 * 
* (1) Use of this source code, wether identical, changed or altered is allowed, for both commercial and non-commercial use.   * 
*                                 * 
* (2) This source code may be changed and altered freely to be used only within your entity/organisation, given that a notice of all * 
*  changes introduced are listed and included at the end of a copy of this exact copyright notice, including the name and date of * 
*  the entity/organization that introduced them.                     * 
*                                 * 
* (3) The redistribution or publication to the public of this source code, if changed or altered, is striclty prohibited using any * 
*  medium not owned, and/or controlled by Mo Enterprises Inc unless a written consent has been requested and recieved by   * 
*  representatives of Mo Enterprises Inc.                       * 
*                                 * 
* (4) The distribution of any work to the public derived through the use of this source code, wether identical, changed or altered, * 
*  is allowed, as long as it in full compliance of (3).                   * 
*                                 * 
* (5) Mo Enterprises Inc considers the techniques and design patterns employed in this source code as unique and making the   * 
*  redistribution of this source code with altered names, and/or a rearrangement of code as a severe breach of the copyright law * 
*  and this license. Mo Enterprises Inc reserves all rights to puruse any and all legal options.         * 
*                                 * 
* (6) All copies of this source code, wether identical, changed/altered must include this entire copyright notice, list all changes * 
*  made including the name and date of the entity/organization that introduced them, as wel as the following disclaimer:   * 
*                                 * 
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND            * 
*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED             * 
*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE               * 
*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR            * 
*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES             * 
*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;             * 
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND             * 
*  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT              * 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS             * 
*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                 * 
*                                 * 
* Please contact us on [email protected]{at}momomo.com if you have an improvement to this source code you'd like to contribute.   * 
* We'll make sure to include your name and/or organisation as a contributor if accepted.            * 
**************************************************************************************************************************************/ 

import java.util.IdentityHashMap; 
import java.util.Map; 

/** 
* @Author Mo. Joseph 
* 
* Consider memory leakage usage. 
* None of the public methods below should be used outside of the interface extending Stateful! 
*/ 
@SuppressWarnings("unchecked") 
public interface Stateful { 
     /** 
     * @Private access only! Strict enforcement, otherwise risks for memomry leaks! 
     */ 
     static final Map<Stateful, IdentityHashMap<Class<State>, State>> STATES = new WeakIdentityHashMap<>(); 

     /** 
     * @Protected access only! Strict enforcement, otherwise risks for memomry leaks! 
     * 
     * Note, this method can not be generified! 
     * If so, then it will conflict when a class implements several Stateful interfaces. 
     */ 
     default <Y extends Stateful, T extends State<Y>> T $(Class<T> clazz) { 
       synchronized (this) { 
         IdentityHashMap<Class<State>, State> map = STATES.get(this); 
         if (map == null) { 
           STATES.put(this, map = new IdentityHashMap<>()); 
         } 

         State state = map.get(clazz); 
         if (state == null) { 
           try { 
             map.put(cast(clazz), state = clazz.newInstance()); 
           } catch (Throwable e) { 
             throw new RuntimeException(e); 
           } 
         } 
         return (T) state; 
       } 
     } 

     /** 
     * @Protected access only! Strict enforcement, otherwise risks for memomry leaks! 
     * May only be extended from within an interface that implements Stateful. 
     */ 
     static interface State<Y extends Stateful> {} 

     /** 
     * @Private 
     * Util method for casting used here. Simple casting won't work for some reason. 
     */ 
     static <T>T cast(Object obj){ 
       return (T) obj; 
     } 



     /******************************************************************************* 
     * Example code below: 
     *******************************************************************************/ 
     public static void main(String[] args) { 
       Person mo = new Person(); 
       mo.setName("Mo. Joseph"); 
       mo.setStreet("Mansion Street 1"); 
       System.out.println(mo.getName()); 
       System.out.println(mo.getStreet()); 

       Pet garfield = new Pet(); 
       garfield.setName("Garfield"); 
       System.out.println(garfield.getName()); 

       Person santa = new Person(); 
       santa.setName("Santa"); 
       santa.setStreet("North Pole Street 1"); 
       System.out.println(santa.getName()); 
       System.out.println(santa.getStreet()); 

       mo.setName("mo"); 
       System.out.println(mo.getName()); 
       System.out.println(santa.getName()); 
       System.out.println(garfield.getName()); 
       System.out.println(santa.getStreet()); 
     } 

     public static class Person implements Named, Address { 

     } 

     public static class Pet implements Named { 

     } 

     public static interface Named extends Stateful { 
       static class State implements Stateful.State<Named> { 
         private String name; 
       } 

       public default void setName(String name) { 
         $(State.class).name = name; 
       } 

       public default String getName() { 
         return $(State.class).name; 
       } 
     } 

     public static interface Address extends Stateful { 
       static class State implements Stateful.State<Address> { 
         private String street; 
       } 

       public default void setStreet(String street) { 
         $(State.class).street = street; 
       } 

       public default String getStreet() { 
         return $(State.class).street; 
       } 
     } 
     /************************************************************************************/ 

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