hi
wie isn die syntax wenn ich mehrere dinge extenden will?
bla extends bla1 und bla 2
greez
wie isn die syntax wenn ich mehrere dinge extenden will?
bla extends bla1 und bla 2
greez
class MyPanel extends javax.swing.JPanel implements java.io.Serializable, java.awt.ActionListener {
// ...
}
Nicht wenn man verstanden hat, wieso das so gehandhabt wird.noisebreath hat gesagt.:lame....
noisebreath hat gesagt.:wie isn die syntax wenn ich mehrere dinge extenden will?
bla extends bla1 und bla 2
public interface Bla extends Bla1, Bla2 {
}
Leroy42 hat gesagt.:Wow!
Würde mich mal interessieren.![]()
Bin auch dabei.Zed hat gesagt.:Du hast es uns angeboten. Will auch mitraten!!!
#include <iostream>
using namespace std;
class A
{
public : virtual void f() { cout << "A" << endl; };
};
class B : virtual public A
{
public : virtual void f() { cout << "B" << endl; };
};
class C : virtual public A {};
class BC : public B, public C {};
int main()
{
BC bc;
C* c = & bc;
c->f();
system("PAUSE");
return 0;
}
public interface Cat {
public void purr();
}
public interface Dog {
public void bark();
}
public class Angora implements Cat {
public void purr() {
System.out.println("purrrrrr");
}
}
public class Beagle implements Dog {
public void bark() {
System.out.println("wuff");
}
}
public class BioLab {
public static Object breed(final Object... args) {
Set<Class> interfaces = new HashSet<Class>();
for(Object o : args) {
for(Class<?> interf : o.getClass().getInterfaces()) {
interfaces.add(interf);
}
}
return Proxy.newProxyInstance(BioLab.class.getClassLoader(), interfaces.toArray(new Class[0]),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
if (arguments == null) {
arguments = new Object[0];
}
for(Object o : args) {
for(Method m: o.getClass().getMethods()) {
if (m.getName().equals(method.getName())) {
Class[] classes = m.getParameterTypes();
if (classes.length == arguments.length) {
boolean match = true;
for(int i = 0; i < arguments.length; i++) {
if (! classes[i].isAssignableFrom(arguments[i].getClass())) {
match = false;
break;
}
}
if (match) {
return m.invoke(o, arguments);
}
}
}
}
}
return null;
}
});
}
//for testing
public static void main(String... args) {
Object chimaira = breed(new Beagle(), new Angora());
System.out.println(chimaira instanceof Dog);
System.out.println(chimaira instanceof Cat);
((Dog)chimaira).bark();
((Cat)chimaira).purr();
}
}
Bin kein C++ Experte, meine aber mich erinnern zu können das der Kompiler festlegt, wie die Aufrufe aufgelöst werden können, und zwar anhand der Reihenfolge der vererbenden Klassen.Jupp, es wird B ausgegeben. Eine genaue Begründung traue ich mir nicht zu (nur ein paar Arumentationsbrocken). Das überlasse ich den C++-Experten.
class BC : public B, public C {};
class BC : public C, public B {};
Bedenkst du dabei auch dass es Methoden gibt die jedes Objekt immer anbietet wie equals, hashcode, toString etc. pp.? :wink:Zed hat gesagt.:Mann muss aber schon zugeben das man das Problem umgehen kann durch eine konkrete Bezeichung bei Methoden.
Wer eine Mehrfachvererbung nutzt und Methoden gleich benennt ist selber schuld wenn er erst debuggen muss um den Fehler zu finden.
Möchte mal jemand testen was passiert wenn anstatt
die Reihenfolge umgedreht wird:Code:class BC : public B, public C {};
Code:class BC : public C, public B {};
@_flix
In dem Fall:
Es gibt die klassen A,B,C
B erbt von A und C erbt von B
kannst du z.B. annehmen du hast eine Methode doSomething() in der Klasse A
Nun sagst du das B von A erbt. Dann hast du die zwei Möglichkeiten, dass B die Methode doSomething() überschreibt, oder sie so lässt wie sie in A definiert wurde.
In der klasse C, die von B erbt, ist es nun so dass die Methode doSomething() halt die ursprüngliche Form hat (wenn du sie nicht in B überschireben hast), oder sie so aussieht wie du sie in B überschrieben hast.
Aber du hast z.B. nicht das Problem, wie es Marco13 in seinem C++ Programm gezeigt hast. Du kannst sofort anhand des Quellcodes entscheiden, ob die Methode doSomething() das macht was sie in A macht, oder das was sie in B macht.
Die "Vererbungsreihenfolge" spielt keine Rolle.Das erstellte Objekt bc ist vom Typ BC, welches zuerst B erbt:
Das gezeigte Programmfragment ist ein Puzzle. Puzzles gibt es in jeder Sprache, aber niemand würde sowas wirklich schreiben und einsetzen.C++ Standard §10.1 (2) hat gesagt.:the order of derivation is not significant except as specified by the semantics of initialization by constructor (12.6.2), cleanup (12.4), and storage layout (9.2, 11.1).
Als Beispiel: B erbt von A1 und A2, ich habe in beiden Klassen foo(String) und bar(int), ich will nun foo() von A1 und bar() von A2 verwenden - was dann?
#include <iostream>
#include <string>
struct A1
{
virtual void foo(std::string const& str)
{
std::cout << "foo in A1\n";
}
virtual void bar(int x)
{
std::cout << "bar in A1\n";
}
};
struct A2
{
virtual void foo(std::string const& str)
{
std::cout << "foo in A2\n";
}
virtual void bar(int x)
{
std::cout << "bar in A2\n";
}
};
struct B : A1, A2
{
};
int main()
{
B b;
b.A1::foo("hello");
b.A2::bar(42);
}