Как создать реплику класса 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
Вы можете использовать рефакторинг: Заменить наследование делегированием, которое в основном (как показано в предыдущих ответах) создает переменную экземпляра желаемого типа и реализует все ее методы в новом классе и передает им сообщение.
Создайте поле для суперкласса, настройте методы для делегирования суперклассу и удалите подкласс.
Вы заметите, что это много печатает, когда пригодится хорошая IDE.
На следующем видео показано, как это делает IntelliJ IDEA 9.
Ответ 8
Если вы просто хотите переопределить часть поведения String, вы можете попробовать использовать динамический прокси. Посмотрите java.lang.reflect.Proxy
в API.