Java接口上的多重inheritance

我认为多重inheritance在Java中总是非法的,但是这段代码编译:

public interface A { void a(); } public interface B { void b(); } public interface AB extends A, B { } 

AB这样的空接口会被视为不良做法吗? 有没有办法在避免空接口(使用generics或其他方式)的同时实现类似的东西?

注意:我不是在问如何通过接口模拟多重inheritance。 我意识到我可以做到以下几点:

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

由于各种原因,我需要一个具有两种方法的接口。

不允许多次inheritance实现 。 但是,组件可以inheritance多个接口。

inheritance多个接口不成问题,因为您只是定义要实现的新方法签名。 它是多个function副本的inheritance,传统上被视为导致问题,或者至少是混乱(例如, 死亡的钻石 )。

接口可以扩展一个或多个其他接口。 您还可以在类中实现多个接口。 这是合法的,因为接口只是合同 – 没有实现。 你只是简单地定义一个类能够做什么的合同,而不说任何关于类如何做的事情。

实现接口不是“inheritance”,即扩展类时。

实现接口用于声明类“看起来像”某事,而扩展类用于声明类“是”某事。

“看起来像”多件事情是可以的,但不是“成为”多件事。

使用扩展多个接口的空接口作为将一组接口收集到单个接口中以传达更广泛但重用的API的方式没有任何问题。

在这个相关问题中 ,Jay为此提供了答案。 区别在于指定实现与接口。

仅当两个函数具有相同名称时,才会出现实现问题。 这是因为“我使用f()的实现是什么?”这个问题没有明显的选择。 有多个实现。

两个具有相同function名称的接口不会发生此问题,因为它不需要进行此选择。 相反,您只需要实现自己的函数版本。

作为一个例子,我们可以看一下允许多重inheritance的对应物–C ++ 。 此链接很好地解释了一些事情,并提供了一些代码/图像示例。 需要注意的一点是,由于您需要明确地确定函数所属的类的范围,因此您可以轻松地缓解C ++中的问题。

但是在Java中,我们真的不必这样做(因为只有附加到对象的方法,如果你愿意的话),因此没有一个方法来调整范围。 我们必须引用父类的唯一选项是使用super关键字,或使用static函数。 因此,在Java中没有明确的选择来解决这个问题,除非对系统进行额外的更改,否则收益甚微。

试试这个,它需要Java 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 opensource@{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, 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 > T $(Class clazz) { synchronized (this) { IdentityHashMap, 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 {} /** * @Private * Util method for casting used here. Simple casting won't work for some reason. */ static 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 { 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
{ private String street; } public default void setStreet(String street) { $(State.class).street = street; } public default String getStreet() { return $(State.class).street; } } /************************************************************************************/ }