2012-01-03 8 views
9

私は抽象親クラスを持っています。force toString()メソッドを実装するすべてのサブクラスにしたいと思います。サブクラスでtoString()を実装する

しかし置く:

public abstract String toString(); 

は、コンパイル・エラーを引き起こしている:

Repetitive method name/signature for method 'java.lang.String toString()' in class ... 

私は、これはすでにのtoStringが定義されたグルーヴィーによって引き起こされる可能性があると信じています。あなたはtoString()を上書きするためにそれらを強制することはできませんが、あなたは、抽象親クラスでは、のtoString()は、サブクラスがする必要がありますこれは、抽象メソッド、youGottaOverideToString()別の男を呼び出すことができた

+0

.NETには基本実装を上書きするための 'new'キーワードがあります。 Javaに似たものがあれば私は興味があります。 –

答えて

10

toString()はすでにjava.lang.Objectクラスの一部で、すでにデフォルトの実装があります。したがって、基本的にサブクラスに強制的に実装することはできません。このような動作を強制したい場合(理由はわからない)、次のようなことができます。

public class abstract SuperClass 
{ 
    public abstract String myToString(); 

    public String toString() 
    { 
    //print super class fileds 

    //enable subclass to do the printing 
    myToString(); 
    } 
} 
+0

説明と回避策をお寄せいただきありがとうございます – Dopele

+0

パンゲアの回答はうまくいきますが、これまでに行ってクライアントがあなたの道やハイウェイを受け入れるようにする場合は、抽象クラスでtoString()をfinalにする必要があります。私の意見では、あなたはここであなたのクライアントをあまりにも多くのコントロールを主張するかもしれません。 toStringの実装にjava.lang.Objectが与えるものを超えて強制するのはなぜですか? –

6

短い答え:不可能です。 ロング答えは:あなたが代わりに次の手順を実行して、これを回避しようとすることができ、親クラスで実装します。

public final String toString() { 
    getString(); 
} 

public abstract String getString(); 

これは「のgetString()」メソッドを実装する必要があるために子クラスが発生します。しかし、子クラス(孫)クラスの子は、子クラスが "getString()"メソッドを実装している場合、そのメソッドを強制的に実装する保証はありません。例:

A is the parent class, with the getString() method. 
B extends A, and implements the getString() method. 
C extends B, doesn't have to implement the getString() method. 

希望に役立ちます:)

13

これは私のために動作します。これは新しいのですか他の人はそれを見逃しましたか?

public abstract class Filterable 
{ 
    @Override 
    public abstract String toString(); 
} 

public class ABC extends Filterable 
{ 
    // Won't compile without toString(); 
} 
+0

私はこのパターンも問題なく使用します –

+2

親クラスが '抽象化'されている場合にのみ動作しますが、これはおそらくここで必要とされたものでしょう。 – Menachem

0

抽象クラスを拡張しているすべてのクラスを特定し、それらがtoString()を宣言していることを確認する単体テストを作成できます。スキャンするにはReflectionsライブラリを使用できます。

@Test 
    public void validateToString() { 
    final Reflections dtoClassesReflections = new Reflections(new ConfigurationBuilder() 
     .setUrls(ClasspathHelper.forPackage("my.base.package")) 
     .filterInputsBy(new FilterBuilder() 
     .include(".*Dto.*") // optionally filter only some particular classes 
     .exclude(".*Test.*")) // exclude classes from tests which will be scanned as well 
     .setScanners(new SubTypesScanner(false))); 

    final Set<Class<?>> allDtoClasses = dtoClassesReflections.getSubTypesOf(YourAbstractClass.class); // you set your class here (!!). You can set Object.class to get all classes 

    allDtoClasses.forEach(dtoClass -> { 
     logger.info("toString() tester testing: " + dtoClass); 

     try { 
     dtoClass.getDeclaredMethod("toString"); 
     } catch (NoSuchMethodException e) { 
     fail(dtoClass + " does not override toString() method"); 
     } 
    }); 


    } 
関連する問題