2010-01-15 22 views
7

Necesito crear una clase con exactamente los mismos métodos que java.lang.String.¿Cómo crear una réplica de clase String?

¿Cuál es la mejor manera de hacer esto en Java?

Sé que no puedo extender la clase de cadena como es final. No estoy buscando soluciones donde necesito copiar el código fuente de java.lang.String. Por ejemplo, supongamos que necesito la funcionalidad length() dentro de mi clase personalizada llamada MyString, que tiene un método 'myLength() `correspondiente.

¿Cuál es la mejor manera de implementar myLength()?

No estoy buscando varios algoritmos para averiguar la longitud de una cadena sino para reutilizar el método Stringlength(). Ahora, una vez que tengo lista la clase MyString, debería ser capaz de usarla en cualquier lugar para mis manipulaciones personalizadas.

+7

¿Cuál es el problema real que está tratando de resolver? – ZoFreX

+0

Estoy tratando de averiguar qué patrón de diseño sería el más adecuado para este tipo de problema. – Thunderhashy

+1

Siempre me he preguntado, ¿por qué String es definitivo en Java? Claro, proporciona toda la funcionalidad que siempre necesité, y nunca pensé en una operación que requiriera una extensión de la clase String, ¡pero igual nunca sabrá lo que alguien podría necesitar! – Alex

Respuesta

5

Desde su pregunta suena como lo que busca es sencilla delegation:

class MyString { 

    String delegate; // The actual string you delegate to from your class 

    public MyString(String delegate) { 
    this.delegate = delegate; // Assign the string that backs your class 
    } 

    int length() { 
    return delegate.length(); // Delegate the method call to the string 
    } 

    // other methods that delegate to the string field 
} 
+0

Esto se ve bien. ¿Pero puedo hacer MyString strAbc = "This is my String"? Estoy buscando una réplica exacta de String. En su solución, necesitaría pasar el String en el constructor. – Thunderhashy

+0

@ Harsha, lo que quiere simplemente no es posible. –

+0

@Paul ¿Puedes explicarlo? – Thunderhashy

2

hacer una nueva clase (que necesitará un paquete diferente, por supuesto, aplicar la misma interfaz y añadir todos los métodos públicos de la clase String (Lee el javadoc para asegurarse de que tienes todo).

I tiene que asumir esta es la tarea.

8

Desde final clases no pueden tener subclases, crear una nueva clase que tiene una instancia String dentro y operar en este objeto.

public class MyString { 
    private String s; 

    public MyString(String s) { 
    setInternalString(s); 
    } 

    public int myLength() { 
    return getInternalString().length(); 
    } 

    private void setInternalString(String s) { 
    this.s = s; 
    } 

    private String getInternalString() { 
    return this.s == null ? "" : this.s; 
    } 
} 
+2

Delegación llamada. –

3

Supongo que te refieres a java.lang.String. Sin embargo, no puede reemplazar String con su propia clase. Puede crear otra clase con los mismos métodos (copiando el código fuente y cambiando la declaración del paquete), pero no podrá pasar instancias de esa clase a métodos que requieran un String.

Lo que hace surgir una pregunta importante: ¿por qué crees que quieres hacer esto?

+0

No quiero crear una clase simplemente copiando todos los métodos de la clase String. Esta pregunta me fue hecha en una entrevista. – Thunderhashy

+3

Tal vez fue una pregunta capciosa, y se suponía que debías explicarles por qué al hacerlo esto te impediría interoperar con la API Java casi existente. – erickson

+1

Otra respuesta a la entrevista sería señalar que String implementa CharSequence y puede crear otras implementaciones. Por supuesto, eso no ayuda si las API que usan la cadena ersatz requieren un String en lugar de una CharSequence. –

0

Si solo desea anular una parte del comportamiento de Cadena, podría intentar usar un proxy dinámico. Consulte java.lang.reflect.Proxy en la API.

+0

El soporte de proxy dinámico incorporado solo funciona con interfaces. ASM y otras bibliotecas de códigos de bytes pueden funcionar con clases, pero no estoy seguro acerca de las clases finales. – erickson

3

Proxy patrón de diseño, supongo. Aunque es una pregunta estúpida (no un reflejo del que pregunta, sino de la persona que se lo preguntó en una entrevista de trabajo). ¿Posiblemente la persona que te pregunta no se dio cuenta de que String es final? De lo contrario, no puedo pensar por qué incluso preguntarían.

+1

Creo que el verdadero desafío radica en el hecho de que la cadena es definitiva. De lo contrario, la respuesta es bastante simple ¿no? Simplemente extienda String y listo. – Thunderhashy

1

Es posible utilizar la refactorización: Replace inheritance with delegation, que básicamente es (como se muestra en las respuestas anteriores) para crear una variable de instancia del tipo deseado e implementar todos sus métodos en la nueva clase y pasarles el mensaje.

Cree un campo para la superclase, ajuste los métodos para delegar a la superclase y elimine la subclase.

https://www.refactoring.com/catalog/repInherWithDel.gif

Se dará cuenta de que esto es un montón de escribir, que es cuando un buen IDE es muy útil.

El siguiente video muestra cómo IntelliJ IDEA 9 lo hace.

http://img43.imageshack.us/img43/5647/capturadepantalla201001k.png

8

El paso por las distintas respuestas aquí, y las actualizaciones y aclaraciones Askers, parece que lo que el autor de la pregunta quiere es una clase que se ve, huele y suena como una cadena, pero no lo es.

es decir que les gustaría ser capaz de hacer:

MyString string = "String!!"; 

esto no puede funcionar, ya que java.lang.String es una clase final, y por lo que cada "String" que el compilador produce será un objeto java.lang.String, ya que este es no es un objeto MyString, no se pueden asignar el uno al otro.

En los idiomas débilmente tipados, usted podría crear dicha clase, ya que si una clase se ve, huele y suena como duck, entonces, a todos los efectos, es un pato. Java, sin embargo, es un lenguaje fuertemente tipado, y un pato es solo un pato si es del Anatidae family of birds.

+0

+1 eso es cierto. El usuario de SO ha solicitado una réplica de cadena y no un delegado, donde un delegado seguirá creando un objeto String. –

Cuestiones relacionadas