嗨,我是java的新手....从目标c(iphone背景)移动
我们所知道的一切 这里我们不能使用多重继承....
替代方式是界面......
我的问题是......通过接口进行继承是否有意义...因为我们必须在我们的类中定义函数代码.......这里只有帮助部分是变量... 它就像目标c中的单个.h类......
我只谈论那个界面的功能......为什么要在那里宣布......只是为了保存2或3行......就是这样......
请说明为什么没有多重继承(原因很简单......)。
我知道这可能是个问题,但.........
我有点黑暗请帮助.....
答案 0 :(得分:4)
我喜欢Stephan Schmidt的这个答案。他清楚地解释了这一点,
的 http://codemonkeyism.com/java-interview-questions-mutliple-inheritance/
强>
Java是否支持多重继承?
嗯,显然Java在这个词的经典意义上没有多重继承。所以正确的答案应该是“不”,或“不,但是”或“是,但是”。从那里可以探索几种方式。大多数情况下,我首先询问Java语言设计者是否过于愚蠢而无法实现多重继承?为什么C ++人员会实现呢?我们主要登陆Diamond Anti-Pattern然后: 在具有多重继承和知识组织的面向对象编程语言中,当两个类B和C继承自A,而D类继承自B和C时,钻石问题是一种模糊性。如果D中的方法调用定义的方法在A中(并且不覆盖该方法),B和C以不同方式覆盖该方法,然后从哪个类继承:B或C?
另一种探索方式是Java如何“模拟”多重继承?可能已经浮出水面的答案就是接口。然后,我们通常会讨论Java中的接口,过去是否,何时以及如何使用它们。什么是接口有益,他喜欢它们吗?我可以探索他在建模方面有多好,有时候会让他用界面绘制图表。我们继续讨论Java中的接口问题,当两个接口具有相同的静态字段并且类实现两者时会发生什么 - Java中的某种“多重继承”:
public interface I1 { String NAME = "codemonkeyism"; } public interface I2 { String NAME = "stephan"; } public class C implements I1, I2 { public static void main(String[] args) { System.out.println(NAME); } }
保持原样,语言设计师认为这在Java中不起作用:
C.java:3: reference to NAME is ambiguous, both variable NAME in I1 and variable NAME in I2 match System.out.println(NAME); ^ 1 error
有很多方法可以与候选人一起探索,例如:什么是接口方法的修饰符。 mixins或traits是否比接口更好地解决了diamand问题?或者它们和多重继承一样糟糕?因为我不再非常喜欢继承,并且认为大多数用法都是代码气味,所以人们也可以讨论继承的缺点 - 例如,与候选人的联系。 为什么呢?
为什么我会问这个问题,我从中学到了什么?继承是OO中的一个非常基本的概念,每个Java开发人员都应该理解它。反思他的工作并超越了解语法也是一个必不可少的特质,因此存在多重继承问题。我更喜欢产生许多探索机会的问题。继承问题就是其中之一:多重继承,语言设计,代码异味,解决方案,接口,基于角色的开发。
答案 1 :(得分:2)
我想在之前的回答中添加一些内容。
正如您从Tilsan所给出的深刻解释中所理解的那样,Java不支持多重继承。
或者,您应该使用一种委托设计模式。我知道有时代码看起来比使用多继承完成的代码更冗长,但这是我们必须付出的代价。
您问了一个问题为什么需要创建实现多个接口的类?我问你一个问题为什么你需要接口呢?我认为答案是,这允许您将接口(契约)与具体实现分开,使模块独立,简化重新分解并使程序更灵活:只有在具体实现被接口隐藏时才能切换实现。
如果您的类可以在不同的上下文中用作A和B(其中A和B是接口),则该类应该实现2个接口。
示例:假设您有一个业务接口Foo,它只声明一个方法
int foo(String str);
现在你创建了几个实现Foo的类A和B:
public class A implements Foo {
public int foo(String s) {
return s.length();
}
}
public class B implements Foo {
public int foo(String s) {
return s.hashCode();
}
}
现在你想创建Foo的集合:
Collection<Foo> collection = new ArrayList<Foo>();
collection.add(new A());
collection.add(new B());
使用此集合的代码对具体实现一无所知,但它并不打扰调用foo()。
现在您希望对此集合进行排序。其中一种方法是实现另一个可比较的接口:
public class A implements Foo, Comparable<Foo> {
public int foo(String s) {
return s.length();
}
public int compareTo(Foo o) {
return getClass().getName().compareTo(o.getClass().getName());
}
}
完成后你可以说:
Collections.sort(collection);
并且将根据compareTo()中定义的规则对集合进行排序。
现在您可能希望序列化A和B的实例。为此,您必须实现另一个Serializable接口。幸运的是,Serializable是一个特殊的接口,不会声明任何方法。 JVM知道序列化和绝望化作为Serializable实例的对象。
public class A implements Foo, Comparable<Foo>, Serializable {
public int foo(String s) {
return s.length();
}
public int compareTo(Foo o) {
return getClass().getName().compareTo(o.getClass().getName());
}
}
B级看起来一样。
现在我们可以说:
DataOutputStream os = new DataOutputStream(new FileOutputStream("/tmp/foo.dat"));
os.writeObject(new A());
os.writeObject(new B());
os.flush();
os.close();
并将我们的对象存储在文件/tmp/foo.dat
中。我们可以稍后阅读这些对象。
我试图说明为什么我们需要实现多个接口的类:每个接口都为类提供了行为。 Comparable允许对这些实例的集合进行排序。 Serializable允许序列化等。