2017-05-09 1 views
2

Ich weiß nicht, ob dies überhaupt möglich ist, aber ich dachte an etwas in Java:Vererben kinderspezifische Methode von den Eltern

Wenn ich eine abstrakte Elternklasse haben, kann ich dies tun:

Wenn ParentClass dann ein Kind hat und ich diese Methode überschreiben möchte, hat die Kindklasse noch eine ParentClass add(ParentClass, ParentClass) Methode.

Gibt es eine Möglichkeit, die Elternfunktion für jedes Kind selbst ableiten zu lassen?
Ich weiß nicht, ob ich Wortlaut bin es richtig, aber so etwas wie:

// ParentClass.java 
public ParentClass add(ParentClass a, ParentClass b); 

// Foo.java 
@Override // or an equivalent 
public Foo add(Foo a, Foo b) {} 

// Bar.java 
@Override 
public Bar add(Bar a, Bar b) {} 

Beachten Sie, wie jedes Kind nicht eine ParentClass add(...) Funktion haben, sondern eine für jeden ihrer eigenen Typen stattdessen?

Offensichtlich kann ich nur diese selbst machen, aber ich will in der Lage sein, überschreibbare in Eltern zu schaffen. Ich habe das vorher noch nie in der Praxis gesehen, also zweifle ich an seiner Existenz. Ich möchte nur mit jemandem klären, der ein höheres Java-Wissen besitzt als ich. Vielen Dank.

In der Theorie, die ich keine Sprache erraten jemals getan hat, so etwas wie dieses:

public child add(child a, child b); 
// where *child* is the type of the child inheriting the method 
+2

Haben Sie bereits über die Verwendung von Generika nachgedacht? –

+0

Warum keine Generika? Sie sind die Lösung für dieses Problem. –

+0

@OliverCharlesworth Sorry, ich habe noch nie ein Generikum gesehen, das wie SkinnyJ benutzt wurde. Das ist perfekt**. – finnrayment

Antwort

4

In Java Kovarianz von Parametern eines Verfahrens ist nicht erlaubt.
Diese geerbte Methode: public ParentClass add(ParentClass a, ParentClass b); ist für alle untergeordneten Elemente zulässig, da sie die Angabe einer Unterklasse von ParentClass als Parameter ermöglichen.
Es ist flexibler.
Wenn Sie diese Flexibilität nicht möchten und einen bestimmten Typ für Parameter in der geerbten Methode erzwingen möchten, sollten Sie eine generische abstrakte Klasse verwenden.

public abstract class ParentClass <T extends ParentClass <?>>{ 
    public abstract ParentClass<?> add(T a, T b); 
} 

Und in der Kinderklasse könnten Sie schreiben:

public class ChildClass extends ParentClass <ChildClass>{ 
    public ParentClass<?> add(ChildClass a, ChildClass b){ 
     .... 
    } 
} 
+0

Schön! Nur eine Sache; Gibt es irgendeine Möglichkeit, den generischen Typ irgendwie automatisch auf die Klasse des Kindes zu setzen, ohne sie einzubeziehen? d. h. "" vollständig entfernen? – finnrayment

+0

Nein, du kannst nicht.Die Java-Sprache funktioniert nicht auf diese Weise. Sie müssen es explizit angeben. – davidxxx

+0

Alles klar, ich werde leben. : P – finnrayment

2

So etwas wie dies mit Generics arbeiten konnte:

public abstract class ParentClass<T extends ParentClass> { 
    public abstract T add(T a, T b); 
} 

class Foo extends ParentClass<Foo> { 
    @Override 
    public Foo add(Foo a, Foo b) { 
     return null; 
    } 
} 

class Bar extends ParentClass<Bar> { 
    @Override 
    public Bar add(Bar a, Bar b) { 
     return null; 
    } 
} 
+0

Danke! Genau das suche ich. Nie gesehen Generika wie diese verwendet, aber es ist perfekt. – finnrayment

0

Sie können eine Schnittstelle mit Typ parameter.Refer zu https://docs.oracle.com/javase/tutorial/java/generics/types.html für Details

public interface Adder<T> { 
    T add(T a, T b); 
} 

dann die Schnittstelle implementieren definieren.

public class Foo implements Adder<Foo> { 

    @Override 
    public Foo add(Foo a, Foo b) { 
     // implement the details 
    } 

} 
+3

Was ist diese Antwort, die über die beiden bereits eingereichten Antworten hinausgeht? –