解答大家大部分疑惑
我也是小白,面对大家大部分问题,这是我的见解:(有点啰嗦)
首先要明白,重写的equals方法中有多个return,只要执行一个,方法中剩下的语句就不会执行
1、contains()方法的实质:假设有一个集合L:{A,B,C},其中A,B,C三个对象都是Course类型的,每个对象都有两个属性:id和name。现在集合L调用contains方法,来判断某个对象e是否在这个集合内:L.contains(e);它的执行过程是,系统自动让集合中的每一个对象调用一次equals方法,即A.equals(e),B.equals(e),C.equals(e),只要这三个equals方法有一个返回TRUE,则contains方法就返回TRUE,证明对象e 存在集合中。所以重写equals方法,就是重写contains方法
2、第一个if(this==obj)意为,是不是对象调用equals方法来和自己比较,自己和自己比较当然相同啦,结果返回TRUE,然后执行权回到主方法中
3、第二个if(obj==null)意为:被比较的对象obj是不是空的,由于只有非空对象才能调用equals方法,所以若obj是空对象,则结果肯定是FALSE
4、第三个if(!(obj instanceof Course))和下面强制类型转换,意为,判断被比较对象obj的实例是不是Course类型的。这里的被比较对象使我们在主方法中创建的一个Course对象(Course obj=new Course();),我们只给它赋予了一个属性name,注意此对象的引用叫obj,他是Course类型的,这个对象的实例叫new Course();他也是Course类型的。然后这个obj被当做形参传给contains方法,这里向上转型object类,也就是说隐形的执行了一句:(Object)obj,这里改变类型的只是对象的引用obj(其类型从Course变成Object),实例依然是Course类型的,所以用instanceof关键字(他判断的是实例的类型),判断其类型应为Course类的。然后我们要用到这个对象的属性,由于此时对象的引用是object所以,还得再把它变回来。
这里给大家举个例子:有一个人叫小明,他的妈妈叫小红,有一件事只有叫小明的人才能干。这个人就相当于一个对象,他的名字小明就相当于对象的引用,她的妈妈是小红相当于对象的实例,即:无论这个人叫小明也好,该名称小刚也罢,他都是小红的儿子,这点是不变的(对应程序中的向上转型成object,实例依然为Course类型),然而我们要让一个人做什么事,肯定会说:“那个谁谁谁,你去干什么什么……”,我们用的是这个人的名字,也就是这个对象的引用,由于文中提到有一件事只有叫小明的人才能做,所以即使人还是这个人,但他的名字已经叫小刚了,不叫小明了,所以还得把他的名字换回来(对应程序的强制类型转换)
5、if(this.name.equals(course.name))为什么用equals,而不用“==”。首先注意,这里调用equals方法的主体是this.name 他是个string类型的变量,而我们重写的是Course类型的equals方法,所以这里不是equals方法的递归。第二点,一个内存中只能存放一种内容,然而相同的内容可以存在于多个内存之中,也就是说同内存肯定同内容,但同内容不一定同内存。“==”比较的是内存是否相同,而equals比较的是内容,this.name和course.name这两个分别是不同对象的属性,而不同对象肯定不同内存,所以用“==”的话无论怎样都会返回FALSE。