像这里,为了把Collections.sort改为按对象的ID来排序,所以重写compareTo方法,并且用了this.getId().compareTo(o.getId()) 语句,我不懂的是,这里的compareTo方法已经重写为只接收Student类型的对象了,为什么它还能接收o.getId()返回的字符串类型值呢?
但是对于comparator的compare方法重写中,老师还是用comparable例子中compareTo那个语句比较并返回。但是我自己试了一下仿照compareTo那种形式用compare方法来判断,如上图示。这个时候编译器报错了,说是只能接收Student类型的对象,不能接收字符串。
希望有前辈可以解答一下,为什么comparable的compareTo()方法示例中,明明定义了只接收Student对象,但是在return那里还是可以接受字符串。 而在comparator的compare()方法重写示例中使用类似的思路写就会报错呢?
首先你要了解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隐藏了的情况)。
首先可以知道compareTo这个方法的返回值是int 型,故return 这里是对两个对象的比较而返回值 显示了二者的大小;你明白了这些再按照人家说的去领会,会更容易
听了你的解释,清晰很多了,非常感谢!