10.9 Object类

万事万物皆对象。 Everything is object. 这是面向对象里面很著名的一句话,而Java把这句话贯彻到底:它定义了一个Object类(Object就是对象的意思),作为所有类的“祖先”类。根据继承的理论,所有类都是Object 类型! java作为一个纯面向对象的语言,它有一个严格的继承体系,而这个体系的根,就是这个Object。也许有人会有疑问——自己定义的类呢,也是Object的子类吗?例如这样:
public class Tester{
}
其实就算是自定义的类,也是Object的子类,编译器会在类的后面加上继承关系:
public class Tester extends Object{
}
任意一个对象,都是Object对象,都可以类型转化成Object。
看下面代码的例子,ob是一个Object对象,test是一个String对象,同时它也是一个Object对象,所以这个赋值是合法的。
String test="Good!";
Object ob=test;
这里还是有例外的,那就是基本变量,例如int 、double这些,因为它们都不是类,所以并不是Object对象,为了统一,每个基本变量类型都有一种包装类与之对应。可参考9.4包装类
int i=8;
Object o=i;
/**
实际上是 Object o=(Integer)i;
 */

 Object里面有几个方法,任何类都可以复写它们。如果要适应所有的类,那么这些方法无疑是非常具有通用性,下面我们来看几个:
返回类型
方法名及参数
说明
示例
boolean
equals(Object ob)
比较当前对象和ob是否相等,两个对象是否相等,是和这个类的定义决定的,例如两个学生对象是否相等,可以判断这两个对象是否有相同的学号就可以了
String类重写了这个方法,比较两个字符串内容是否相等
String
toString()
返回一个表达这个对象的字符串
假设有一个复数类,那么可以复写这个toString方法,以a+bi的形式打印这个复数
Object
clone()
克隆一个对象
这是另一个生成对象的方法,如果类提供了这个方法,那么可以通过它生成当前对象的复制品
ClassgetClass()取得一个Class对象
Class是一种记录此对象的方法和属性的一种类型
equals方法,我们在String类已经遇见过,事实上,String的equals就是复写了Object的equals,如果有这样的问题:需要比较某个类的对象是否相等,那么就需要复写这个方法。例如Stduent类,需要比较两个对象是否相等(是否是同一个学生):
public static void main(String[]args){
    Student stu1=new Student();
    stu1.name="John";
    stu1.id="123456";
    stu1.clazz="23计算机应用9班";
    Student stu2=new Student();
    stu2.name="John";
    stu2.id="123456";
    System.out.println(stu1.equals(stu2));
}
这就有一个问题,stu1和stu2什么情况下才相等?这就需要Student的设计者来决定,于是Student类就需要重写equals方法。(通过eclipse的菜单的"源码"-》"覆盖和实现方法",再勾选Object类的equals方法,可以自动生成方法的框架)。下面的代码,Stduent类添加了equals方法,两个对象是否相等的条件是:它们的id和name属性不能为空;他们的id和name属性分别相等。
public class Student{
    String name;
    String id;
    String clazz;
    public void printName(){
        System.out.println("名字是:"+name);
    }
    public void setName(String name){
        this.name=name;
    }
    @Override 
    public boolean equals(Object obj){
        Student stu=(Student)obj;
        if(stu.id==null || stu.name==null || this.id==null || this.name==null){
            return false;
        }
        return this.id.equals(stu.id)&& this.name.equals(stu.name);
    }
    public static void main(String[]args){
        Student stu1=new Student();
        stu1.name="John";
        stu1.id="123456";
        stu1.clazz="23计算机应用9班";
        Student stu2=new Student();
        stu2.name="John";
        stu2.id="123456";
        System.out.println(stu1.equals(stu2));
    }
}
运行代码可见打印true,说明stu1和stu2是同一个学生。
String类就重写了equals方法,专门用来比较两个字符串的内容是否相等。
第二个方法toString,用来将对象转换成字符串。例如直接打印一个对象:
public class Student{
    String name;
    String id;
    String clazz;
    public void printName(){
        System.out.println("名字是:"+name);
    }
    public void setName(String name){
        this.name=name;
    }
    @Override 
    public boolean equals(Object obj){
        Student stu=(Student)obj;
        if(stu.id==null || stu.name==null || this.id==null || this.name==null){
            return false;
        }
        return this.id.equals(stu.id)&& this.name.equals(stu.name);
    }
    public static void main(String[]args){
        Student stu=new Student();
        stu.name="John";
        stu.id="123456";
        stu.clazz="23计算机应用9班";
        System.out.println(stu);
    }
}
直接运行代码,也就是打印stu对象,将会出现诸如“ccc.Student@15db9742”这样的输出,如果有把对象直接转化成字符串的需求,那么就要重写Object的toString方法:
public class Student{
    String name;
    String id;
    String clazz;
    public void printName(){
        System.out.println("名字是:"+name);
    }
    public void setName(String name){
        this.name=name;
    }
  
    @Override 
    public boolean equals(Object obj){
        Student stu=(Student)obj;
        if(stu.id==null || stu.name==null || this.id==null || this.name==null){
            return false;
        }
        return this.id.equals(stu.id)&& this.name.equals(stu.name);
    }
    @Override 
    public String toString(){
        StringBuffer buffer=new StringBuffer();
        buffer.append("此学生的学号是").append(this.id).append(",姓名是").append(this.name).append(",班级是").append(this.clazz);
        return buffer.toString();
    }
    public static void main(String[]args){
        Student stu=new Student();
        stu.name="John";
        stu.id="123456";
        stu.clazz="23计算机应用9班";
        System.out.println(stu);
    }
}
此时再打印Student对象,那么就会按照上面代码的toString方法来构建字符串打印。上面运行的输出是“此学生的学号是123456,姓名是John,班级是23计算机应用9班”
在eclipse里,也提供了方便的方法来继承父类的方法,我们就可以发现Object里面的所有可继承方法,随便找一个类,在代码区域右键点击鼠标,然后选择“源代码(source)”-> “覆盖/实现方法(Override/Implement Methods)”: