2012-01-03 10 views
9

Tengo una clase primaria abstracta, y me gustaría que force todas las subclases para implementar el método toString().Implementación Force toString() en las subclases

Sin embargo poner:

public abstract String toString(); 

está causando un error de compilación:

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

Creo que esto podría ser causado por maravilloso que ya ha definido toString.

Gracias

+0

.NET tiene una palabra clave 'new' para anular una implementación base. Tengo curiosidad si Java tiene algo similar. –

Respuesta

10

El toString() es parte de la clase java.lang.Object que ya tiene una implementación predeterminada para él. Entonces, esencialmente no puedes obligar a las subclases a implementarlo. Si desea forzar este tipo de comportamiento (no sé por qué), entonces usted puede hacer algo, como a continuación

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

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

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

Gracias por la explicación y la solución – Dopele

+0

La respuesta de Pangea funcionará, pero si va hasta aquí y obliga a sus clientes a aceptar su camino o la carretera, probablemente debería estar haciendo toString() final en la clase abstracta. En mi opinión, sin embargo, podría estar ejerciendo un poco de demasiado control de sus clientes aquí. ¿Por qué estás forzando una implementación de toString más allá de lo que te ofrece java.lang.Object? –

0

No se puede obligar a anular toString(), pero se puede, en la clase padre abstracta, tienen toString() llama a otro método abstracto m, youGottaOverideToString(), que tendrán que subclases implementar.

6

Respuesta corta: no es posible. Respuesta larga: Usted podría tratar de evitar esto haciendo lo siguiente en su lugar, poner en práctica en la clase padre:

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

public abstract String getString(); 

Esto hace que la clase hija que necesita para poner en práctica el método "getString()". Sin embargo, la clase de hijo del niño (nieto) no tiene ninguna garantía de verse obligado a implementar ese método si la clase de niño implementa el método "getString()". Ejemplo:

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. 

Espero que ayude :)

13

Esto funciona para mí. ¿Es esto nuevo o otros lo extrañaron?

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

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

También uso este patrón sin ningún problema –

+2

Solo funcionará si la clase principal se hace 'abstracta', pero eso es probablemente lo que se desea aquí de todos modos. – Menachem

0

Puede escribir una prueba unitaria que localizará todas las clases ampliando su clase abstracta y verificará que declaren toString(). Para escanear puede usar la biblioteca 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"); 
     } 
    }); 


    } 
Cuestiones relacionadas