Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较Java子类_Java - Fatal编程技术网

比较Java子类

比较Java子类,java,Java,我的应用程序可以比较同一抽象父类的任意两个子类的实例。我希望将它们进行如下比较: 如果它们是不同的子类,则父类应进行比较 如果它们是相同的子类,则子类应进行比较 这些类将通过树映射进行比较,因此我可以选择使用比较器,或者实现Comparable(或者两者兼而有之) 我可以想出几种方法来做到这一点,但它们都有点混乱和容易出错。有优雅的解决方案吗 提前谢谢…您可以试试 // Parent: @Override public final int compareTo(Parent other) {

我的应用程序可以比较同一抽象父类的任意两个子类的实例。我希望将它们进行如下比较:

  • 如果它们是不同的子类,则父类应进行比较
  • 如果它们是相同的子类,则子类应进行比较
  • 这些类将通过树映射进行比较,因此我可以选择使用比较器,或者实现Comparable(或者两者兼而有之)

    我可以想出几种方法来做到这一点,但它们都有点混乱和容易出错。有优雅的解决方案吗

    提前谢谢…

    您可以试试

    // Parent:
    @Override
    public final int compareTo(Parent other)
    {
      if (getClass() == other.getClasss()) {
        // same type -> pass it to subclass implementation
        return this.subCompare(other)
      }
    
      // different type -> do the comparison here based on Parent's logic
      // ...
    }
    
    protected int subCompare(Parent other)
    {
      // this should not be called directly
      return 0; // could throw an exception here too
    }
    
    // Derived1:
    @Override
    protected int subCompare(Parent other)
    {
      // this method is only called from Parent
      Derived1 other1 = (Derived1) other;
      // do the comparison based on Derived1's logic
    }
    

    类似地,对于其他派生类

    这不是对您问题的直接回答,而是:
    我相信你所做的事情容易出错,而且有问题。
    compareTo
    方法施加的相等性测试通常应返回与
    equals
    方法相同的结果。也就是说,
    compareTo
    方法施加的顺序应与
    equals
    一致
    如果违反此约定,您可能会遇到排序集合(您正在使用的)问题。
    我为什么这么说:
    在某些情况下,您希望将比较委托给父类,这一事实向我表明,您已在子类中添加了一个值组件。

    如果您这样做了,那么就不可能保留
    equals
    契约,并且您可能会遇到排序容器的问题(请参见上文)

    无论哪种方式都很容易出错。您可以在子类中执行以下操作:

    类子类1。。。{

    public boolean equals(Object o) {
      if(o instanceof Subclass1) {
        return super.equals(o);
      }
    
      ... compare subclasses
    }
    

    }

    类层次结构是否应可扩展?
    =>如果不可扩展(或很少会扩展),您可以实现Comperator,以便所有比较代码都位于一个位置

    是否有不止一种方式来排列对象? =>如果是这样,那么您必须为每个订单使用comperator

    compareTo(其他)
    (或
    compare(o1,o2)
    )从以下三种情况调用:

  • 其他.class的此实例
    (即o2.class的o1实例):
    • this.class应该比较
      this
      o2
      ,因为它比其他.class有更多的信息
  • 此.class的其他实例
    (即
    o1.class的o2实例
    ):
    • other.class应比较
      other
      this
      和this.class.compare,以翻转结果并返回结果
  • 存在第一个共同祖先P,因此
    此P实例
    和&
    其他P实例
    • P应该比较
      其他
      :递归调用super.compareTo(其他)并返回结果

  • 我现在就是这样做的。我认为这是最优雅的:

    public abstract class ParentClass implements Comparable<ParentClass> {
        // compareTo(ParentClass) is implicitly abstract
    }
    
    
    public class SubClass1 extends ParentClass /* Comparable<> is implicitly implemented */ {
        @Override
        public int compareTo(ParentClass another) {
            SubClass1 subAnother = (SubClass1) another;
            return /* result of sub-class comparison */;
        }
    }
    
    
    public class MyComparator implements Comparator<ParentClass> {
        @Override
        public int compare(ParentClass lhs, ParentClass rhs) {
    
            // Are lhs and rhs instances of the same sub-class?
            if(!lhs.getClass().equals(rhs.getClass()))
                // They are different. Use parent class comparison.
                return /* result of parent class comparison */;
    
            // They are the same. Use sub-class comparison.
            return lhs.compareTo(rhs);
        }
    }
    
    公共抽象类ParentClass实现了可比较的{
    //compareTo(父类)是隐式抽象的
    }
    公共类子类1扩展了ParentClass/*Compariable,隐式实现了*/{
    @凌驾
    公共整数比较(父类另一个){
    第1子类另一子类=(第1子类)另一子类;
    返回/*子类比较结果*/;
    }
    }
    公共类MyComparator实现了Comparator{
    @凌驾
    公共整数比较(父类lhs、父类rhs){
    //lhs和rhs实例是否属于同一子类?
    如果(!lhs.getClass().equals(rhs.getClass()))
    //它们是不同的。请使用父类比较。
    返回/*父类比较结果*/;
    //它们是相同的。使用子类比较。
    返回左侧比较(右侧);
    }
    }
    
    然后我只需将
    MyComparator
    的一个实例传递到
    TreeMap
    。它处理不同的子类比较,或者将比较传递给相同的子类


    我不喜欢的是,如果
    另一个
    是另一个子类的实例,则
    子类1.compareTo()
    将抛出
    ClassCastException
    。但是,只要我确保子类仅由MyComparator比较,我就不必担心这一点。你所说的“类将由树映射进行比较”是什么意思?既然你提到了Comparable和Comparator,那么我们可以假设比较的结果有三种可能性—“小于”,“大于”和“等于”?如果比较排除了其中一个选项的可能性,那么您不应该使用这些接口。您的意思是通过反射来比较类吗?每个类都有哪些方法和属性?这是一项非常困难的任务,因为compare()的契约规定了传递性:如果b1>b2(与B子类比较),如果a>b1(与基类比较),那么必须有a>b2(与基类比较)。考虑到基类比较对子类比较一无所知,这是很难实现的。@JBNizet-虽然我不认为OP的想法一定很好,但我认为只要子类排序始终是“子比较”,保持传递性并不困难将可能使父级compare()成为最终的,以避免意外重写。否则,只要不需要在层次结构中的任意深度做出决策,这就行了。仅供参考。“this instanceof other.getClasss()”在Java中不是有效语句……是的,您只需要“getClass()==other.getClass()”谢谢。这是接近我已经在做的,可能是优雅的,因为它将得到。除了我使用的是Comparator和Comparable的混合解决方案:Comparator检查它们是否是不同的子类,如果是,则处理比较。否则,它将调用subclass.compareTo()。@BarryFruitman您可以通过首先根据基类规则进行比较来改进保证,并且只有当它们相等时,才打破