Реализация одного интерфейса в двух классах. Один унаследован у другого. Java
Проблема состоит в том, что никак не выходит реализовать один и тот же интерфейс в дух классах одновременно. К примеру, есть класс "Point2D" который реализует интерфейс "Comparable< Point2D>", у него унаследован класс "Point3D", в котором хотелось бы написать реализацию интерфейса "Comparable< Point3D>".
Не предоставляется возможным, разные аргументы. Как можно исправить?
Ответы (2 шт):
Суть в том, что вы пытаетесь реализовать один и тот же интерфейс дважды.
Смотрите, если
public class Point2D implements Comparable<Point2D>
и в то же время
public class Point3D extends Point2D
то Point3D уже имплементирует Comparable<Point2D>.
Это не единственная проблема, с которой можно столкнуться, используя интерфейс Comparable. Но всё можно решить, используя Comparator. Как-то так:
class Point3DComparator implements Comparator<Point3D> {
public int compare(Point3D a, Point3D b){
//Ваш код здесь
}
}
Ну, а дальше методы sort() самых разных коллекций все (ну или почти все, не помню) принимают в качестве аргумента такой кастомный компаратор и сортируют без проблем.
Вам правильно советует @ЮрийСПб. Давайте посмотрим и проведем небольшой анализ на совместимость с SOLID. А конкретнее с S- single responsibility principle и L- Liskov substitution principle
Вариант 1.
public abstract class Point{
}
public class Point3D implements Comparable<Point3D>{
....
public int compareTo(Point2D anotherPoint)
{
....
}
}
public class Point2D implements Comparable<Point2D>{
.....
public int compareTo(Point2D anotherPoint)
{
....
}
}
Вариант 2. (Допустим такой вариант)
public class Point2D implements Comparable<Point2D>{
.....
public int compareTo(Point2D anotherPoint)
{
....
}
}
public class Point3D extends Point2D implements Comparable<Point3D>{
....
public int compareTo(Point2D anotherPoint)
{
....
}
}
- По принципу единственной ответственности. Классы реализованные по варианту 1 не противоречат ему потому что нет необходимости думать за методы предка.
- По принципу Лисков. Поскольку вы наследуете 3D от 2D в варианте 2. Ваше приложение не должно менять поведение заменой предка потомком. Этого у вас не получится поскольку
compareToметоды различны.
PS. Собственно постановка Лисков в принципах SOLID очень сильно напрягает по поводу наследования классов и наследовать просто так желания не возникает.