1

在重构 Java 项目以使用组合而不使用继承时,我仍然存在一个问题,即执行集合的多态排序。

继承示例:

public class AClass
{
    private List<OneClassOfManyThatRequireSortedInstances> unsortedList;

    public List<OneClassOfManyThatRequireSortedInstances> getSortedList()
    {
        List<OneClassOfManyThatRequireSortedInstances> sortedList = new ArrayList(this.unsortedList);
        Collections.sort(sortedList, SuperClassOfManyThatRequireSortedInstances.orderComparator);

        return sortedList;
    }
}

现在,在重构之后;类OneClassOfManyThatRequireSortedInstances不再从 abstract 继承,SuperClassOfManyThatRequireSortedInstances而是Collections.sort()期望相互比较的实例。

重构它的最佳方法是什么?

编辑:

为了完整性;我添加了 Comparator 实现并进一步澄清了问题。

public class SuperClassOfManyThatRequireSortedInstances
{
    private int order;

    public static final Comparator<SuperClassOfManyThatRequireSortedInstances> orderComparator = new Comparator<SuperClassOfManyThatRequireSortedInstances>()
    {
        public int compare(SuperClassOfManyThatRequireSortedInstances o1, SuperClassOfManyThatRequireSortedInstances o2)
        {
            if ((o1 == null) && (o2 == null))
            {
                return 0;
            }
            if (o1 == null)
            {
                return -1;
            }
            if (o2 == null)
            {
                return 1;
            }
            return (new Integer(o1.getOrder()).compareTo(new Integer(o2
                .getOrder())));
        }
    };


    public int getOrder()
    {
        return this.order;
    }


    public void setOrder(int order)
    {
        this.order = order;
    }
}

问题的症结在于重构为组合后,OneClassOfManyThatRequireSortedInstances不再"is a" SuperClassOfManyThatRequireSortedInstances等代码被破坏。

许多类,如OneClassOfManyThatRequireSortedInstances不再有一个共同的父母。因此,Collections.sort()不能在这些类中使用Comparator. 像OneClassOfManyThatRequireSortedInstancesnow 这样的类反而有一个SuperClassOfManyThatRequireSortedInstances成员;一种"has a"关系。

4

3 回答 3

5

假设有两个类,CarTrain。您可以创建一个类似的接口

public interface SpeedProvider {
    int getSpeed();
}

然后两者CarTrain实现SpeedProvider接口

public class Car implements SpeedProvider {
    int maxSpeed = 220;

    @Override
    public int getSpeed() {
        return maxSpeed;
    }
}

public class Train implements SpeedProvider {
    int maxSpeed = 300;

    @Override
    public int getSpeed() {
        return maxSpeed;
    }
}

最后,您可以实现一个Comparator比较两个SpeedProvider

public class VehicleComparator implements Comparator<SpeedProvider> {
    @Override
    public int compare(SpeedProvider o1, SpeedProvider o2) {
        /* ... */
        return 0;
    }
}
于 2013-05-20T10:12:40.377 回答
1

这个问题没有意义。Comparator<T>用于合成。使用继承时的替代方法是Comparable<T>. 你的问题又回到了前面。

于 2013-05-20T10:24:35.567 回答
0

您可以通过接口签订合同,其中您有某些排序方法,这些方法基于一组特定的字段(如使用的超类)返回。然后,您可以拥有一个进行排序计算的类和另一组基于不同的字段/组合集进行排序的类。

然后,您可以简单地传递一个 Comparator 的实例,该实例将执行所需的排序并检查 instanceof ...如果未实现特定接口,您可以选择抛出错误或记录并悄悄地返回默认值。

于 2013-05-20T09:51:28.247 回答