Zusicherung als Funktionsparameter

Bouyo

Mitglied
Ich frag mich gerad wenn ich z.B.

Code:
public interface MyInterface1 {
    ....
}

Code:
public interface MyInterface2 extends MyInterface1 {
    ....
}

Code:
public class MyClass {
          public void doSomething(MyInterface1 obj) {
                  ...
          }

          public void doSomething(MyInterface2 obj) {
                  ...
          }
}

Code:
public class TestClass1 implements  MyInterface1 {
           ...
}

Code:
public class TestClass2 extends TestClass1 implements  MyInterface2 {
           ...
}

Code:
public class TestClass3 extends TestClass2 {
           ...
}

Code:
public class MainClass
          main() {
                TestClass1 tc1 = new TestClass1();
                TestClass2 tc2 = new TestClass2();
                TestClass3 tc3 = new TestClass3();

                MyClass mc = new MyClass();

                // aufruf von  public void doSomething(MyInterface1 obj)
                mc.doSomething( tc1 ); 

                // aufruf von  public void doSomething(MyInterface1 obj)
                // oder doSomething(MyInterface2 obj)
                mc.doSomething( tc2 ); // auf ruf von 

                // aufruf von  public void doSomething(MyInterface1 obj)
                // oder doSomething(MyInterface2 obj)
                mc.doSomething( tc3 );
}

Ist es eigentlich in Java sichergestellt, das bei tc2 und tc3 MyClass.doSomething(MyInterface2 obj) aufgerufen wird, oder
wird MyClass.doSomething(MyInterface1 obj) aufgerufen), weil tc2 und tc3 ja das Interface MyInterface1 implementiert hat? Und wenn letzteres, gibt es eine Möglichkeit, ohne den Funktionnamen zu ändern, tatsächlich MyClass.doSomething(MyInterface2 obj) aufgerufen wird?
 

Marco13

Top Contributor
Wie man sieht, wenn man
Java:
interface MyInterface1
{
}

interface MyInterface2 extends MyInterface1
{
}

class MyClass
{
    public void doSomething(MyInterface1 obj)
    {
        System.out.println("For 1 " + obj);
    }

    public void doSomething(MyInterface2 obj)
    {
        System.out.println("For 2 " + obj);
    }
}

class TestClass1 implements MyInterface1
{
}

class TestClass2 extends TestClass1 implements MyInterface2
{
}

class TestClass3 extends TestClass2
{
}

public class ParameterTest
{
    public static void main(String[] args)
    {
        TestClass1 tc1 = new TestClass1();
        TestClass2 tc2 = new TestClass2();
        TestClass3 tc3 = new TestClass3();

        MyClass mc = new MyClass();

        // aufruf von public void doSomething(MyInterface1 obj)
        mc.doSomething(tc1);

        // aufruf von public void doSomething(MyInterface2 obj)
        mc.doSomething(tc2);

        // aufruf von public void doSomething(MyInterface2 obj)
        mc.doSomething(tc3);
    }
}
ausführt: Es wird immer das spezifischste genommen. Siehe auch Chapter 15. Expressions

Schon durch
Java:
interface MyInterface2 // Auskommentieren dieses Teils: extends MyInterface1
wird das nicht mehr eindeutig, und dann beschwert er sich auch.
 
N

nillehammer

Gast
Marco hat's schon geschrieben und mit Testcode belegt. Man sollte dennoch mit dem Überladen von Methoden sehr sparsam umgehen. Es verwirrt i.d.R. die Nutzer Deiner Api und zwingt manchmal zu expliziten Casts. Außerdem impliziert ein gleicher Name, dass die Methoden ähnliches tun. Das mag in Deinem konkreten Fall so sein, muss ja aber nicht immer so bleiben.
 
N

nillehammer

Gast
Mittels
Java:
 mc.doSomething((MyInterface1)tc2);
kannst du die andere Methode verwenden.
Danke für das Beispiel. Das meinte ich mit expliziten Casts. Sieht doch einfach nur häßlich aus...
 

Ähnliche Java Themen

Neue Themen


Oben