2013-08-20 7 views
11

Ich möchte Unterklasse erzwingen, um eine implementierte Methode meiner Mutterklasse zu implementieren. Ich sehe dies Java - Force implementation of an implemented method, aber ich kann meine Mutterklasse nicht in eine abstrakte Klasse konvertieren.Wie erzwinge die Implementierung einer Methode in der Unterklasse ohne Verwendung von abstrakten?

public class myMotherClass { 

    myMethod { 

     ...some code .. 

    } 

} 

public class myClass extends myMotherClass { 

    myMethod { 

     ... other code ... 
    } 

} 

Also, in diesem Beispiel möchte ich myClass myMethod implementieren implementieren.

Sorry für mein Englisch ...

+1

Kurz gesagt: Sie können nicht, ohne es abstrakt zu machen –

+0

@stonedsquirrel Was ist mit einer Schnittstelle? –

+0

Dies ist nicht möglich mit Annotationen oder durch Auslösen einer Ausnahme, wenn die Klasse die Methode nicht implementiert? – Maniz

Antwort

16

Sie nicht eine Unterklasse eine Methode zu überschreiben erzwingen. Sie können es nur zwingen, eine Methode zu implementieren, indem Sie sie abstrakt machen.

Also, wenn Sie nicht machen myMotherClass abstrakt können Sie nur eine andere übergeordnete Klasse einführen, die myMotherClass und Delegierten des Verfahrens erstreckt, die umgesetzt werden müssen:

public abstract class EnforceImplementation extends myMotherClass { 

     public final void myMethod(){ 
      implementMyMethod(); 
     } 

     public abstract void implementMyMethod(); 
} 

EDIT

ich eine andere interessante Art und Weise gefunden zur Lösung des Problems in der hemcrest API, die z verwendet von Mockito.

public interface Matcher<T> extends SelfDescribing { 

    /** 
    * Evaluates the matcher for argument <var>item</var>. 
    * <p/> 
    * This method matches against Object, instead of the generic type T. This is 
    * because the caller of the Matcher does not know at runtime what the type is 
    * (because of type erasure with Java generics). It is down to the implementations 
    * to check the correct type. 
    * 
    * @param item the object against which the matcher is evaluated. 
    * @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>. 
    * 
    * @see BaseMatcher 
    */ 
    boolean matches(Object item); 

    /** 
    * This method simply acts a friendly reminder not to implement Matcher directly and 
    * instead extend BaseMatcher. It's easy to ignore JavaDoc, but a bit harder to ignore 
    * compile errors . 
    * 
    * @see Matcher for reasons why. 
    * @see BaseMatcher 
    */ 
    void _dont_implement_Matcher___instead_extend_BaseMatcher_(); 
} 

Die Schnittstelle legt ein Verfahren _dont_implement_Matcher___instead_extend_BaseMatcher_. Natürlich hindert es andere nicht daran, die Schnittstelle Matcher zu implementieren, aber es führt den Entwickler in die richtige Richtung.

Und die BaseMatcher Klasse implementiert die _dont_implement_Matcher___instead_extend_BaseMatcher_ Methode als final

public final void _dont_implement_Matcher___instead_extend_BaseMatcher_() { 
    // See Matcher interface for an explanation of this method. 
} 

Schließlich glaube ich, dass dies ein Design-Problem, weil die BaseMatcher obviouosly implementiert Logik, die jedes Matcher implementieren sollte. Daher wäre es besser gewesen, die Matcher eine abstrakte Klasse zu erstellen und eine Template-Methode zu verwenden.

Aber ich denke, sie taten es, weil es der beste Kompromiss zwischen Bytecode-Kompatibilität und neuen Funktionen war.

4

könnten Sie Ihre Hierarchie überarbeiten, so dass Ihre konkreten Klassen nur Blätter des Baumes sind.

Statt

myClass extends myMotherClass 

Betrachten

myClass extends myMotherAbstractClass 
myMotherClass extends myMotherAbstractClass 

Auf diese Weise die abstrakte Klasse von beiden instanziiert Klassen vererbt wird. Es ist wahrscheinlich in diesem Fall die myMotherClass wäre extrem dünn, nur die Implementierung von myMethod.

-1

Wenn Sie wirklich zwingen möchten, die Methode zu implementieren, verwenden Sie interface.

public interface MyInterface{ 

    void myMethod(); 
} 

Nun, wenn jemand von dieser Schnittstelle als MyClass implements MyInterface implementieren möchten, müssen Sie implementieren myMethod();

public MyClass implements MyInterface{ 

    public void myMethod{ 
    // do something 
    } 

} 
+2

Ich denke nicht, dass dies das Problem lösen wird. – Lokesh

0

Eine Sache, die meisten Menschen mit Blick auf sind, ist die folgende Implementierung (obwohl ich erwähnt es in einem Kommentar sah):

public class MyMotherClass { 

    public void myMethod() { 
     throw new RuntimeException("Method not overwritten"); 
    }  

} 

In den meisten Fällen sollte dies ausreichen, wie Sie irgendeine Form von Akzeptanztests haben sollte (auch wenn es nur die erbende Klasse von Hand testet). In der Theorie stellen Sie immer noch die Möglichkeit vor, dass niemand merkt, dass die Methode nicht bis zur Produktion überspannt wurde.