Метод toString объекта и принцип подстановки Лискова - PullRequest
0 голосов
/ 18 ноября 2018

Каждый класс, прямо или косвенно, наследуется от класса Object.

Класс Object, среди прочих, имеет важный метод, чаще всего переопределяемый: toString.

Вопрос: не приводит ли переопределение этого метода к Лискову?Нарушение принципа замещения в отношении Object класса?

Я приведу пример.

public class Main
{
    public static void main(String[] args)
    {
        Object o = new Object();
        String s = o.toString();
        if (s.indexOf('@') > -1) {
            System.out.println("OK");
        } else {
            System.out.println(":-(");
        }
    }
}

public class MyClass
{
    private int x;

    public string toString()
    {
        return Integer.toString(x);
    }
}

Очевидно, если я заменим new Object() на new MyClass() поведение системыменяется.

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Принцип подстановки Лискова требует только совместимости интерфейса. Это ничего не говорит о базовом поведении. Так например

public interface Text {
    String value();
}

public class SimpleText implements Text {

    private final String value;

    public SimpleText(String value) {
        this.value = value;
    }

    @Override
    public String value() {
        return this.value;
    }
}

public class NumberText implements Text {

    private final Number number;

    public NumberText(Number number) {
        this.number = number;
    }

    @Override
    public String value() {
        return String.format("%.3f", this.number.doubleValue());
    }
}

Вам не нужны детали реализации, поэтому вы можете обменяться ими следующим образом:

//We care only about value() method, not its specific implementation
Text text = new SimpleText("text");
text.value();
text = new NumberText(44);
text.value();
0 голосов
/ 18 ноября 2018

Ну, это вопрос вкуса.Object почти не имеет гарантированных свойств.Так что нарушать особо нечего.

Если вы говорите, что возвращение имени класса - это такое свойство, которое может быть нарушено, то, конечно, подкласс не должен это менять.Но чтение документации Object.toString () показывает, что такой гарантии нет:

Возвращает строковое представление объекта.В общем случае метод toString возвращает строку, которая «представляет» этот объект в текстовом виде.

Итак Я не вижу здесь нарушения LSP .

LSP не говоритчто подкласс должен вести себя точно так же , что и суперкласс.Это сделало бы подклассы совершенно бесполезными.Требуется только, чтобы подклассы соответствовали спецификации суперкласса.


Единственное, что можно упомянуть, это то, что Object применяет бессмысленный метод toString для каждого объекта .Более сложный дизайн, возможно, поместил бы это в интерфейс.

Я думаю, что этот выбор дизайна - просто компромисс, принятый и другими языками, такими как .NET.

...