问答详情
源自:6-8 学生选课--- 实现学生序列排序

关于comparable的compareTo()方法重写和comparator的compare(Student o1, Student o2)方法重写问题

http://img.mukewang.com/55feea2b0001be9804860139.jpg

像这里,为了把Collections.sort改为按对象的ID来排序,所以重写compareTo方法,并且用了this.getId().compareTo(o.getId()) 语句,我不懂的是,这里的compareTo方法已经重写为只接收Student类型的对象了,为什么它还能接收o.getId()返回的字符串类型值呢?

http://img.mukewang.com/55feeb10000198eb04950128.jpg

但是对于comparator的compare方法重写中,老师还是用comparable例子中compareTo那个语句比较并返回。但是我自己试了一下仿照compareTo那种形式用compare方法来判断,如上图示。这个时候编译器报错了,说是只能接收Student类型的对象,不能接收字符串。

希望有前辈可以解答一下,为什么comparable的compareTo()方法示例中,明明定义了只接收Student对象,但是在return那里还是可以接受字符串。 而在comparator的compare()方法重写示例中使用类似的思路写就会报错呢?

提问者:詹士 2015-09-21 01:27

个回答

  • 无动于衷
    2015-09-21 09:38:05
    已采纳

    首先你要了解Override的范围!Overide只在当前类或子类中生效!

    第一个例子里,你重写的是Student类的compareTo()方法,那么当你用一个Student对象去调用这个方法时,执行的就是你Student里重写的方法,这个你应该是明白的。那么看方法中间的代码,

    return this.getId().compareTo(o.getId);这里的this.getId()是String类型的,而String类里的compareTo()方法并没有重写!它调用的是它自身的compareTo()方法(没有重写就是调用父类的)。

    所以,第一个例子,同样是compareTo()方法,一个是Student对象调用,一个是String对象调用,是调用他们各自的方法,你只是重写了Student里面的compareTo()方法而已。

    -----------------------------------------------------------------------------------------

    第二个例子里,不知道你是重写了那个类里的compare(),我就称之为类Unknow。

    你重写的Unknow类里的compareTo()方法,他只能接受Student类型的两个参数,看一下方法里面与第一个例子有和不同:return compare(o1.getId(),o2.getId()),你没有使用对象去调用,那么java里就是当前对象(this),也就是Unknow的对象。就像你在一个类里一个方法里调用另一个方法,都是省略了this.的。

    所以,都是Unknow对象去调用compare()方法,自然调用的是你重写后的方法,只接受Student类型的参数。

    -----------------------------------------------------------------------------------------

    总而言之,你要去理解Override是怎么一回事,Overide是重写父类里的方法,只在当前类或子类中生效(具体就是当你对象调用方法,或者类调用静态方法),而对其他类中的同名方法并不影响。还有就是方法的调用,所有的方法,都是要由对象去调用的(当然静态方法用类即可调用),要弄清楚是哪个类型的对象去调用了方法(特别是像上面说的this,super隐藏了的情况)。

  • 怒放的生命012
    2016-06-12 20:34:41


    首先可以知道compareTo这个方法的返回值是int 型,故return 这里是对两个对象的比较而返回值 显示了二者的大小;你明白了这些再按照人家说的去领会,会更容易

  • 詹士
    2015-09-21 11:04:39

    听了你的解释,清晰很多了,非常感谢!