一.
仅就上一节例子的讲解来看,不用equals方法直接采用= =也是可以的。看着equals方法有点鸡肋。
现在我们做个扩展,不想比较对象的地址值,而是想比较对象的属性,比如说年龄。将此动作作为person对象比较的基本动作,(从这里开始讲解equals方法的更多应用。)
按照之前学习的知识点来看,现在要特定地比较年龄,这样就需要定义特定的函数(如下图所示),唯一让我比较疑惑的就是,本类的方法中形参用的是本类的类型,就是Person p。
如果真是这么写的话,本类中还会存在一个equals方法,从object中继承而来,
这两个功能一样,都是用于比较对象是否相同,只不过一个用于比较对象的年龄。视频中说功能有点重复(我是觉着两者并不重复,比较的点不一样)。既然对象自身具备的是否相同的功能,我们就没有必要重新定义了,我们要做的就是继续保留这个功能的声明,但是我们是不是想建立这个对象自身的一些特有的比较依据啊。父类的方法不错,内容不好,怎么办?这样一来就需要进行复写。
二. equals函数的复写
截图中的equals复写是不对的,这是你自定义的equals方法,相当于和父类中equals方法重载了,下面截图中的方法才是复写。
直接调用对象中的属性进行= =对比。
DOS结果显示错误,为什么?object类是爹,输出语句中p2传递给equals()方法,也就发生了object obj=p2。人对象发生了自动类型提升,专业的说法叫转型。向上一转型,隐藏了子类的特有内容。一隐藏就没了,内存中,没了是我们用不到了。它已经变成了object了,就无法再使用age。想进行扩展性的应用,就要使用多态的形式。而使用多态,就会隐藏子类的属性,因为它们会向上转型。现在还想用,就要进行修改,
结果显示没有问题。
我们知道如果不覆盖这个方法的话,结果是false,因为地址值不一样。我们一旦覆盖了的话,建立的是年龄比较,结果就是ture了。
→讲解这么多,就是说将上一节equals()的用法进行了扩展,从比较对象的地址变为了比较对象的内容。
现在对程序进行修改,创建了d对象,将其传递入equals()函数中,
DOS结果显示错误,显示的报错以前也见过,Demo不能被转成person。问题就在于equals覆盖方法中,接收的范围很广object obj,但是在方法体中又强转成了(person)类,这就和Demo类不合,导致出错。
现在需要对程序进行修改,健壮性判断,对类型进行判断(真会想)
非的时候,返回false;不非的时候,强转正常使用。注意类型的判断用的是instanceof。其实你会发现有些不合适,当类型相同,年龄不同时,也是false。
只有同类型才能进行比较,非同类型还是别比了。也就是说,要是传递的是非同类型,就让你挂掉,在瞎弄。这时候,就需要抛异常。
这里要对抛出的异常进行研究,抛出的是编译时被检测异常,还是抛runtime异常?
我的理解就是runtime异常程序可以正常运行,异常直接被处理了。编译时异常,是在javac阶段就出现问题了。
视频中的讲解,要是想抛编译时检测异常,抛不出来。因为,只要一抛,就需要在函数上进行声明,
而我们这是覆盖父类方法,你声明不出来(这和继承体系有关,要回头去仔细研究)。还有另外一个问题是,如果传递的真不是person类型,还有必要进行处理么?没有必要,那就挂掉,也就是抛出runtime异常。编译时异常是可以立即处理么?
这里runtime异常,名字起的不好。我们异常对象建立的时候,是要根据指定的建立,runtimeException看不出来任何信息,体现不出和类型的关系。这时候就需要自定义一个异常类,同时要继承runtime异常。
视频中讲解:像这种就不需要自定义了,不要自己定义一个自己认识的异常,直接借用java中已有的异常,ClassCastException类型转换异常。
也就是在系统原有的异常类中进行了修改,DOS结果显示没有任何问题。
这种做法要比直接返回false清晰地多。我们应该告诉他,传输的错误类型不让你通过。
这一整个过程中,要注意的细节很多,将之前讲述的很多知识点进行了整合。
我们一般在描述事物的时候,如果该事物能产生很多对象,它属于数据模型中的一种,比如说人,员工,书,mp3,像这种n多具备共性的对象所抽取出来的这么一种类,它通常会代表很多对象的前提下,一般都会具备这个方法。什么具备呢?你只要是定义类,它就具备equals,但这equals只判断地址,是没有意义的,所以我们一般都会复写,应该这么说,(后期开发中,一定要使用的)
光判断地址值,没有太大的意义。
既然都覆盖了,干嘛父类要搞个带内容的?直接把它抽象不就完了么(没听懂)?看上去可以,你知道的是,如果object里面有抽象的方法,意味着什么呢?也就是每建立一个类,什么都不干的情况下,去复写这个方法。可是有必要吗?没有,object做这么一件事儿,我有默认实现,我认为每个对象都可以按地址值进行比较。这种动作我们可能会用到,但是我们更多的是用对象自身的属性,比如说年龄来判断对象是否相同,这个时候,我们就需要复写了。