Это хорошая идея переопределить toString () в абстрактном родительском классе? - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть два класса, подобных приведенному ниже, но стоит ли явно указывать toString() в abstract parent class или мне следует просто опустить его в parent class и override непосредственно в child class

//Parent class
public abstract class Shape {
    @Override
    public abstract String toString();
}

//Child class
public class Circle extends Shape {
    @Override
    public String toString() {
        return "This is a Circle";
    }
}

Ответы [ 2 ]

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

Когда вы объявляете это abstract, вы заставляете подклассы Shape реализовать его, в противном случае это необязательно. Так что это инструмент, который делает toString обязательным, если вы этого хотите.

Конечно, это не гарантируется для реализации в подклассах.

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

В зависимости от того, что вы пытаетесь определить в родительском классе (только концепция, некоторые базовые атрибуты, некоторое общее поведение), вы можете делать несколько вещей. Как сказал @Joakim Danielson, если вы оставите его объявленным как abstract, это заставит неабстрактные подклассы реализовать его, что может привести к повторению некоторого похожего кода в их toString() реализациях. Во многих случаях вы хотите, чтобы toString() перечислял атрибуты и их значения (которые могут находиться в домене родительского класса, возможно, скрытые как private), или сделать что-то вроде:

//Parent class
public abstract class Shape {
    protected abstract double surface();
    @Override
    public String toString() {
        return "I am a geometric shape and my surface is: " + surface();
    }
}

//Child class
public class Circle extends Shape {
    private double r;
    public Circle(double r) {
        this.r = r;
    }
    @Override
    public String toString() {
        return super.toString() + " and my radius is: " + r;
    }
    @Override
    protected double surface() {
        return r * r * Math.PI;
    }
}

//Main class
class Main {
    public static void main(String[] args) {
        Shape c = new Circle(2.0);
        System.out.println(c.toString());
    }
}

//Output
I am a geometric shape and my surface is: 12.566370614359172 and my radius is: 2.0

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

//Child class
public class Square extends Shape {
    private double a;
    public Square(double a) {
        this.a = a;
    }
    @Override
    protected double surface() {
        return a * a;
    }
}

//Main class
class Main {
    public static void main(String[] args) {
        Shape[] shapes = {new Circle(2.0), new Square(3.0)};
        for (Shape shape : shapes)
            System.out.println(shape.toString());
    }
}

//Output
I am a geometric shape and my surface is: 12.566370614359172 and my radius is: 2.0
I am a geometric shape and my surface is: 9.0
...