Как создать реплику класса String?

Мне нужно создать класс с точно такими же методами, как java.lang.String.

Каков наилучший способ сделать это в Java?

Я знаю, что я не могу расширить класс String, поскольку он final. Я не ищу решения, где мне нужно скопировать исходный код java.lang.String. Например, предположим, что мне нужна функциональность length() в моем пользовательском классе с именем MyString, который имеет соответствующий метод myLength().

Каков наилучший способ реализации myLength()?

Я не рассматриваю различные алгоритмы, чтобы узнать длину строки, но повторно использовать метод String length(). Теперь, когда у меня есть класс MyString, я должен использовать его в любом месте для своих пользовательских манипуляций.

Ответы

Ответ 1

С вашего вопроса это похоже на то, что вы ищете просто 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
}

Ответ 2

Просматривая различные ответы здесь, а также уточнения и разъяснения авиалистов, похоже, что то, чего хочет асерист, - это класс, который выглядит, пахнет и звучит как строка, но это не так.

То есть они хотели бы иметь возможность:

MyString string = "String!!";

Это не сработает, поскольку java.lang.String является окончательным классом, поэтому каждый "String", который производит компилятор, будет объектом java.lang.String, поскольку это не объект MyString, который они не могут назначать друг другу.

В слабо типизированных языках вы сможете создать такой класс, поскольку, если класс выглядит, пахнет и звучит как duck, то во всех смыслах и целях это утка. Java, однако, является строго типизированным языком, а утка - только утка, если это происходит из семейства птиц .

Ответ 3

Так как классы final не могут быть подклассы, создайте новый класс, в котором имеет экземпляр String внутри и работает с этим объектом.

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;
  }
}

Ответ 4

Я предполагаю, что вы имеете в виду java.lang.String. Однако вы не можете заменить String на свой собственный класс. Вы можете сделать другой класс с теми же методами (путем копирования исходного кода и изменения объявления пакета), но вы не сможете передавать экземпляры этого класса методам, которым требуется String.

Что вызывает важный вопрос: почему вы думаете, что хотите сделать это?

Ответ 5

Proxy шаблон дизайна, я думаю. Это глупый вопрос, хотя (не размышление об аскете, но о человеке, который его попросил на собеседовании). Возможно, человек, спрашивающий вас, не понял, что String является окончательным? В противном случае я не могу думать, почему они даже спросят.

Ответ 6

Создайте новый класс (для этого потребуется другой пакет, конечно же, реализовать тот же интерфейс и добавить все общедоступные методы из класса String (прочитайте javadoc, чтобы убедиться, что у вас есть все).

Я должен предположить, что это домашнее задание.

Ответ 7

Вы можете использовать рефакторинг: Заменить наследование делегированием, которое в основном (как показано в предыдущих ответах) создает переменную экземпляра желаемого типа и реализует все ее методы в новом классе и передает им сообщение.

Создайте поле для суперкласса, настройте методы для делегирования суперклассу и удалите подкласс.

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

Вы заметите, что это много печатает, когда пригодится хорошая IDE.

На следующем видео показано, как это делает IntelliJ IDEA 9.

Ответ 8

Если вы просто хотите переопределить часть поведения String, вы можете попробовать использовать динамический прокси. Посмотрите java.lang.reflect.Proxy в API.