编程是一种强逻辑的社交活动,建立在人与计算机之间。
高质量的因果关系(物理逻辑)对应着清晰的边界(权限范围),即分工。
Object类——上帝类
Object中的方法,所有类中都有!所有类直接或者间接的父类!
(1)equals方法
public boolean equals (Object obj)//上帝类Object可以接受任何类型的子类对象
判断主动调用此方法的对象是否与要对比的对象相等!(判断两个对象是否相等)
对象打印的默认内容是:对象.toString();
在天然的Object类中的equals方法是比较对象的哈希值(对象引用类型@对象的哈希码)
子类对equals方法进行重写之后,equals就具有了子类需要的对比特点!
equals()方法重写注意点:
- 首先判断传入的对象(obj)与调用equals方法的对象(A)是否同类型;
if(obj instanceof A)
if为真,equals比较才有意义 - 判断为真之后进行强制类型转换(由高到底);
A a = (A) obj;
public boolean equals(Object obj){
if(obj instanceof A){
A a = (A) obj;//强制类型转换
}
}
- 转换完成之后,即可进行同类型的equals比较。
- .equals()比较的内容由.toString()中的内容决定!
class Lian{
public static void main(String[]args){
Person p1=new Person ("海棠",13);
Person p2=new Person ("小鱼",124);
Person p3=new Person ("大鱼",13);
Person p4=new Person ("海棠",13);
sop1(p1);
sop1(p2);
sop1(p3);
sop1(p4);
sop1(p1.equals(p2));
sop1(p1.equals(p3));
sop1(p1.equals(p4));
}
//无回车打印
public static void sop(Object obj){
System.out.print(obj);
}
//有回车打印
public static void sop1(Object obj){
System.out.println(obj);
}
}
//equals方法的复写与使用
class Person{
private String name;
private int age;
Person(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return name+"----"+age;
}
//equals来自于Object类中,所有的子类中均有继承,它的特点是比较两个引用数据变量是否相同,变量本身是用来接收对象的
//即就是在没有被子类复写的情况下,equals为true的唯一情况就是当两个引用数据变量指向同一个变量的时候!!!
public boolean equals(Object obj){//Object类型的引用可以接收任何类型的对象
if(obj instanceof Person){//判断obj接收到的数据类型是不是Person类型;
Person p=(Person)obj;//因为方法已经重写,所以需要将父类Object向下转型之后才能去调用子类属性name,age;
Lian.sop1(this+"=======VS======"+p);//this指向当前类对象
if(this.name.equals(p.name)&&this.age==p.age){
//只有当姓名和年龄都相等的时候为true;
return true;
}
}
return false;
}
//改变之后的equals更加的适用,具有子类需要的特点
}
(2)toString方法
public String toString(){
return /*String类型的返回值*/;
}
//Object类中的默认返回值为:getClass().getName() + '@' + Integer.toHexString(hashCode())
//即就是调用此方法的对象的类型名@十六进制对象哈希码
在单独使用对象的时候会默认调用此方法;
在使用.equals()进行对象比较的时候比较的内容是.toString()输出内容!
toString()方法重写注意点:
- 方法的表达式
- 返回值的组成即就是之后equals比较的内容!
class Lian{
public static void main(String[]args){
Student[]ss=new Student[5];
ss[0]=new Student("大傻","001",84);
ss[1]=new Student("二傻","002",44);
ss[2]=new Student("三傻","003",59);
ss[3]=new Student("四傻","004",74);
ss[4]=new Student("小傻","005",89);
bianLi1(ss);//之所以能够通过遍历数组将对象中的信息全部打印出来,是因为将Object类中的toString方法进行了重写;
//这里有必要重申一下重写的意义:子类对父类方法进行重写,以便于实现自身的特点!
Student.paiXu(ss);
bianLi1(ss);
}
//无回车打印
public static void sop(Object obj){
System.out.print(obj);
}
//有回车打印
public static void sop1(Object obj){
System.out.println(obj);
}
//Student类型的一维数组遍历
public static void bianLi1(Student []a){
for(Student x:a){
sop1(x);
}
sop1("");
}
}
//通过学生的成绩对其指向其对象的引用变量进行排序;
class Student{
private String name;
private String id;
private double chengJi;
Student(){//空参构造
}
Student(String name,String id,double chengJi){//三参构造
this.name=name;
this.id=id;
this.chengJi=chengJi;
}
public String toString(){//神来之笔,重写上帝toString;使得对象的打印变得可用;
return chengJi+"==="+name+"==="+id;
}
//按照成绩从高到低给学生排序---选择排序
public static void paiXu(Student[] s){
for(int i =0;i<s.length-1;i++){
for(int j=i+1;j<s.length;j++){
if(s[i].chengJi<s[j].chengJi){//比较不同对象的成绩高低
Student temp=s[i];//将成绩高的学生对象进行后移,对象移动的同时,对应的成绩也会随之移动,这就保证了成绩对比不会出现重复!
s[i]=s[j];
s[j]=temp;
}
}
}
}
//引用数据变量s的参数类型为Student类型的一维数组,它可以接收Student自己的对象和Student的子类对象;--它对应的元素必定是s[0],s[1]……
/*为什么要在这里使用引用类型变量作为数组中的元素呢?
因为经过重写之后的toString方法已经成为引用变量指向的对象的内容;
所以要做的事情变成了:把所有的指向学生对象的引用变量装进数组之中,然后根据学生对象的成绩高低,将其所对应的对象的引用变量在数组中按照成绩的高低进行遍历,就会得到所想要的结果!
还有一个问题,那就是为什么要使用Student类型的数组作为参数?--因为数组内要存储的数据是Student类型的引用变量值,所以就要是Student类型;*/
}