黑马程序员——面向对象17:Object类

------- android培训java培训、期待与您交流! ----------

1. Object类简介

在Java的API文档中是这么介绍Object类的:Object类是类层次结构的根类,每个类都是Object类的子类。因此,我们在定义一个新类的时候,类名后面总会默认的添加了“extends Object”。也就是说,在创建对象的过程中,子类构造函数总会默认地访问到Object类的构造函数,而且Object类中定义的是所有类中具备的共性方法。

2. Object类方法简介

1) 比较相等——equals()

(a) 比较地址值

代码1:

//简单定义一个Demo类
class Demo{}
class ObjectDemo
{
	public static void main(String[] args)
	{
		//创建两个Demo对象
		Demo d1 = new Demo();
		Demo d2 = new Demo();
		//打印两个Demo对象的比较值
		System.out.println(d1.equals(d2));
 
		//将d1引用的值赋给d3引用,这样d1和d3就都指向了堆内存中的同一片内存
		//换句话说,指向了同一个对象
		Demo d3 = d1;
		System.out.println(d1.equals(d3));
	}
}
运行结果为:

false

true

实际上,equals方法比较的是两个对象在堆内存中的地址值。那么由于d1和d2两个引用指向了两个不同的对象,所对应的地址值必然是不同的;而d1和d3指向同一个对象,地址值当然也就相同了。

通过查阅API文档可知,equals方法的参数列表是:Object obj。也就是说,无论我们后期定义什么样的新类,因为都默认是Object类的子类,所以都可以通过多态方式将对象传入,比较两个对象的地址值,因此该方法的扩展性很好。

(b) 复写equals方法

在实际开发中,我们常常需要通过比较两个对象的属性以判断两者是否相同,仅仅比较地址值是不够的。这时候就需要在新类中通过复写的方式,重新定义Object类中的equals方法。这里我们以Person类为例,比较两对象的age属性来判断两者是否相同。

代码2:

class Person
{
	private int age;
	Person(intage)
	{
		this.ag e= age;
	}
	public int getAge()
	{
		return age;
	}
	/*
		复写了Object类中的equals方法
		首先判断传入的对象是否是Person类型
		如果不是Person类型,直接返回false
		反之,就将其强转为Person类
		最后,通过比较两个Person对象(本类对象和传入对象)的age成员变量值
		来判断两个对象是否相同
	*/
	public boolean equals(Object obj)
	{
		if(!(obj instanceof Person))
 			return false;//专业做法因为抛出异常,后面会详细讲解。
 
		Person p = (Person)obj;
		return age == p.getAge();
	}
}
class ObjectDemo2
{
	public static void main(String[] args)
	{
		Person p1 = new Person(20);
		Person p2 = new Person(24);
		System.out.println(p1.equals(p2));
	}
}
运行结果为:

 

false

在上述equals方法中进行了if语句的判断。这样做的目的是防止向equals方法中传入非Person类对象后造成的类型转换异常。只有经判断确认传入对象是Person类以后,再进行强转动作。这样做提高了代码健壮性。

 2) 打印对象——toString()

toString,顾名思义,是将对象转换成字符串。换句话说,对象中toString方法会返回一个字符串,我们通过一个简单的演示看看返回什么字符串:

代码3:

class Demo{}
class ObjectDemo2
{
	public static void main(String[] args)
	{
		Demo d = new Demo();
		System.out.println(d.toString());
	}
}
运行结果为:

 

Demo@ac6a45

API文档中对该方法的描述是这样的:Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:

getClass().getName() + '@' +Integer.toHexString(hashCode())

关于上述代码的解释如下:

getClass:这个方法会返回一个Class类型的“类文件对象”。所谓Class类就是对每个类对应的xxx.class文件(字节码文件,下同)的描述。由于这些字节码文件都是一些比较复杂的事物,包含了类名、构造方法、一般方法等信息,就像其他事物一样,我们就应该将复杂的事物封装成类进行描述。我们在回过头来说getClass方法,那么对象通过调用这个方法将该对象对应的类文件对象返回来了。

hashCode:返回该对象对应的整型哈希值。关于哈希值后面会有详细说明,大家可以简单那理解为对象在堆内存中的地址值(实际上并不是)。

Class<T>.getName:类文件对象通过调用getName方法就可以获取该对象(由类创建的对象,而不是类文件对象)对应类的名称(以字符串的形式)。

Integer.toHexString:通过Integer类的静态方法toHexString,返回某个整型10进制数对应的16进制数的字符串形式。

通过上述四个方法,并在中间添加一个字符串“@”,就是Object类默认的toString方法的返回结果。

 

小知识点1:

Class类中还定义了名为getMethods的方法,可以通过该方法获取到某个字节码文件中定义的所有方法,包括私有方法。这个动作我们可以称之为反编译,意思就是通过Java的运行文件(字节码文件),可以推测出这个字节码文件中的代码。

 

除此之外,API文档中还有这样的提示:toString 方法返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。也就是说,通过上述代码返回的字符串没有什么太大的实际意义。我们可以通过返回该对象内部封装的特有数据(属性),来对该对象进行描述。比如,以Person类为例,可以通过toString方法返回,姓名、年龄等信息,这样更为直观易于理解。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值