Я думаю, вы, возможно, захотите немного пересмотреть свои знания о OOP, если честно.
На мой взгляд, наследование в OOP определяет то, что называется «есть» отношения между подклассом и суперклассом. Например, если у вас есть класс Shape и класс Square или Circle, мы можем определить отношения «есть-а» между этими классами, потому что «круг» - это «форма, квадрат» - это «форма». Любые методы, которые работают с Shape, могут работать с квадратами и кругами, потому что обычно вещи, которые применяются к Shape, также применимы к Squares и Circles.
Моя проблема с вашим примером заключается в том, что для меня 3DPoint не действительно то же самое, что и 2DPoint. На мой взгляд, никогда не будет легко преобразовать / преобразовать 3DPoint в 2DPoint. Я имею в виду, вы можете попробовать сделать это, просто игнорируя одну из координат (например, z), но для меня это все равно немного странно. Если бы я проектировал это, я бы не делал 3DPoint extends 2DPoint. Я мог бы сделать так, чтобы оба класса расширяли что-то вроде класса Vector, но я бы не стал заставлять 3DPoint расширять 2DPoint. Однако один совершенно правильный метод, который вы могли бы создать в 3DPoint, будет:
class 3DPoint {
...
public 2DPoint to2D() {
return new 2DPoint(x, y);
}
}
Это может быть полезно для вас.
Итак, наконец, совет: если дизайн не предусматривает смысл, то есть вы можете ясно видеть связь «is-a» между двумя классами, тогда я бы сказал, что не используйте расширение / наследование, строки кода, которые вы сохраните, не будут платить за неправильный дизайн в долгосрочной перспективе, особенно по мере того, как ваша кодовая база становится больше.
Надеюсь, это хоть как-то поможет.