2016-05-29 20 views
2

Super-Methode machen Ich weiß, der Titel klingt vielleicht ein bisschen komisch, aber das ist genau das, was ich bereit bin zu tun. Einfach erklärt: Class A ist eine Unterklasse von class B, und class B ist auch eine Unterklasse von class C.Eine Super-Klasse Super-Klasse Super

Nun enthalten alle diese Klassen die Methode m(). In meiner Klasse A, der einzigen, auf die ich Zugriff habe, da die anderen nur zur Laufzeit verfügbar sind, überschreibe ich dieKlasse der m() Methode. Die m() Methode der B Klasse enthält jedoch einen Aufruf an die m() Methode der eigenen Superklasse (das ist C), und, obwohl ich einige Änderungen daran vorgenommen habe, muss ich schließlich auch diese Methode aufrufen.

Ich habe eine Weile gesucht und ich habe gehört, dass dies in ähnlichen Situationen unmöglich wäre, da es "Kapselung brechen würde", und ich verstehe wirklich warum. In meinem Fall mache ich das alles jedoch innerhalb einer überschriebenen Methode, also gibt es irgendeine Möglichkeit, wie ich es tatsächlich so machen kann, dass es so funktioniert? Vielen Dank!

EDIT: Ahm, ich denke, ich habe nicht ruhig gut erklären. Ich überschreibe nur die Methode aus der B-Klasse in meiner C-Klasse. Von dort, innerhalb meiner Methode in der C-Klasse, muss ich die m() -Methode nicht von der B-Klasse aufrufen (was für super.m() funktionieren würde), sondern für die C-Klasse.

Hier ist meine eigentliche Code, wenn sie helfen könnten:

@Override 
public void m() { 

    if(this.au() && this.getGoalTarget() != null && this.vehicle instanceof EntityChicken) { 
     ((EntityInsentient) this.vehicle).getNavigation().a(this.getNavigation().j(), 1.5D); 
    } 

    try { 
     ((EntityMonster) this.getClass().getSuperclass().getSuperclass().getConstructor(World.class).newInstance(this.world)).m(); 
    }catch(InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e){ 
     e.printStackTrace(); 
    } 

} 
+0

sagte Sie Ihre Klasse B-Methode bereits Super (C) Methode aufruft. Was möchten Sie sonst noch? –

+0

Das hört sich alles ein wenig verwirrend an, also 'A erweitert B ', was' C 'ausdehnt - ziemlich genug; und die Methode 'm()' in der Klasse 'B' hat etwas wie' super.m() '- was die Methode' m() 'der Klasse' C' aufruft - ich verstehe nicht, was Sie sagen, das Problem ist hier ? Selbst wenn Sie eine Methode der Basisklasse ('C.m()') überschreiben, hält Sie nichts davon ab, diese Methode mit 'super.m()' von der Kindklasse (Klasse 'B') in Ihrem Fall aufzurufen. – ishmaelMakitla

+0

Ahm, ich glaube, ich habe das nicht gut erklärt. Ich überschreibe nur die Methode aus der B-Klasse in meiner C-Klasse. Von dort, innerhalb meiner Methode in der C-Klasse, muss ich die m() -Methode nicht von der B-Klasse aufrufen (was für super.m() funktionieren würde), sondern für die C-Klasse. – dadus33

Antwort

0

Wollen Sie es auf diese Weise nennen?

public class C { 

    public void m() throws IllegalAccessException, InstantiationException { 
     System.out.println("C"); 
    } 
} 

public class B extends C { 
    @Override 
    public void m() throws IllegalAccessException, InstantiationException { 
     super.m(); 
     System.out.println("B"); 
    } 
} 

public class A extends B { 
    @Override 
    public void m() throws IllegalAccessException, InstantiationException { 
     ((C) this.getClass().getSuperclass().getSuperclass().newInstance()).m(); 
     System.out.println("A"); 
    } 
} 
+0

Hmm, lass mich sehen, ich werde prüfen, ob es jetzt funktioniert, aber ja, das ist es, was ich theoretisch machen will. Es ist jedoch nie schwierig, Reflektionen zu verwenden. – dadus33

+0

Ahm, leider funktioniert es bei mir nicht. Ich erhalte eine Instantiation-Ausnahme: http://hastebin.com/secepakexo.avrasm – dadus33

+0

Unterstützen Sie einen Standardkonstruktor? –

2

Wenn Sie keine Vererbung verwenden können, dann sollten Sie die decorator pattern eine Chance geben.

Im Motivation Abschnitt:

... manchmal (zum Beispiel unter Verwendung von externer Frameworks) ist es nicht möglich, rechtliche oder bequem die Basisklasse zu ändern.

class A { 
    public void m() { 
     System.out.println("A"); 
    } 
} 

class B extends A { 
    public void m() { 
     System.out.println("B"); 
    } 
} 

class C extends B { 

    private final A base; 

    public C(A base) { // pass other needed arguments 
     this.base = base; 
    } 

    public void m() { 
     this.base.m(); // instead of super.m() 
     System.out.println("C"); 
    } 
} 

Sie müssen instanziiert C wie folgt:

In Ihrem Fall Sie die Decorator-Muster auf die C Klasse (die Klasse, die erbt von B) hinzuzufügen Funktionalität nutzen könnten

A base = new A(); 
C c = new C(base); 

Und dann:

c.m(); 

Welche gedruckt werden soll:

A 
C 
+0

Leider kann ich das nicht tun. Vielleicht hätte ich es beim ersten Mal besser erklären sollen ... Ich benutze Bukkit und versuche eigentlich, eine benutzerdefinierte Entität zu erstellen, die das Standardelement ersetzen soll. Während die Klasse für den Standard noch da ist, sage ich Bukkit, dass ich nur meine Klasse anstelle dieser verwenden soll. Außerdem erbt meine Klasse das gesamte Verhalten der Standardklasse, fügt aber etwas hinzu. Wie auch immer, die Sache ist, ich bin nicht derjenige, der meine Klasse instanziiert, Bukkit ist. Und es kann nur mit dem normalen Argument der Standard-Zombie-Klasse (Welt) instanziiert werden ... – dadus33

Verwandte Themen