我认为多重继承一直非法在Java中,但是这个代码编译:
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() {}
}
由于种种原因,我需要有两种方法的接口。
实现的多重继承是不允许的。 组件可以继承多个接口,虽然。
继承多个接口是没有问题的,因为你简单地定义新的方法签名来实现。 这是传统上被视为造成的问题,或者至少是,混乱(例如,功能多份的继承死亡的钻石 )。
一个接口可以扩展的一个或多个其他接口。 您也可以在您的类多个接口。 它是合法的,因为接口只契约 - 没有实现。 你简单地定义为一类能够做什么合同,没有说关于类会怎么做任何事情。
实现接口的不是“遗产”,这是当你扩展一个类。
实现接口来声明一个类“看起来像”的东西,而扩展类来声明一个类“是”什么的。
这是确定为“看起来像”多重的东西,而不是“是”多重的东西。
这没有什么错具有扩展多个接口,收集了一组接口到单一界面来传达更广泛的方式空接口的,但重复使用,API。
在此相关的问题 ,周杰伦提供了一个答案。 所不同的是,指定的执行与接口。
只有当两个函数具有相同的名称,则会出现与执行问题。 这是因为没有明显的选择问题“我用什么实现的F()?” 有多种实现。
因为它并不需要作出这种选择的问题并不具有相同功能名称的两个接口发生。 相反,你只是需要在手边,以便实现自己的功能的版本。
作为一个例子,大家可以看一下,一个对口确实允许多重继承- 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<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;
}
}
/************************************************************************************/
}