Object类详解

本文详细介绍了Java中对象的概念及创建方式,并重点讲解了Object类的toString、equals和hashCode方法的作用与重写技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.Object类

1.Java是面向对象的语言,它的核心思想是:找适合的对象去做适合的事情。那么如何去找适合的对象?

2.创建对象的方式:

(1) 方式一:自定义类,然后通过自定义的类创建对象。

(2) 方式二:sun提供了很多的类给我使用,我们只需要认识这些类,我们就可以通过这些类创建对象了。

3.Object类是所有类的终极父类。 任何一个类都继承了Object类。

二.Object类常用的方法

1.toString( );     

(1) 该方法返回该对象的字符串表示。 是返回一个字符串用于描述该对象的。

(2) 实例一:

public class Demo1 {
	public static void main(String[] args) {
		Object o = new Object();
		System.out.println("toString:"+o.toString());
		System.out.println(o);
	}
}

运行结果如下图所示:


①从运行结果可以看出,toString方法返回的字符串表示为:完整类名+@+对象的哈希码。

②疑问:为什么直接输出一个对象的时候和输出对象的toString方法返回的字符串结果是一样的呢?

通过查看源代码得知,直接输出一个对象的时候,实际上在println方法内部会调用toString方法,把toString方法返回的内容输出。

③查看源代码的方式:

方式一: 按住ctrl键,单击你需要看的源代码.

方式二:把光标移动到你需要查看代码处按下F3.

④查看源代码可以了解别人是如何写出这个技术的,让我们了解的更加的深入。也可以吸收大牛的思想。查看源代码最忌讳的一点: 不要每行代码都弄懂是什么意思,能看个大概猜出意思就足矣。

(3) 实例二:没有重写toString方法

①实例:

class Person {
	int id;
	String name;
	public Person(int id,String name){
		this.id = id;
		this.name = name;
	}
}
public class Demo2 {
	public static void main(String[] args) {
		Person p = new Person(110,"张三");
		System.out.println(p);
	}
}

②运行结果:


③由以上运行结果可知,返回的是这个对象的toString方法返回的字符串,这个字符串对于我们而言一点用都没有。如果我们能够输出一个p对象的时候,输出的格式: 编号:110 姓名: 张三。这样就比较完美了,现在要达到输出一个对象的时候用这种格式的字符串来描述Person对象。目前Object的toString方法无法满足子类的需求,那么这时候我们就应该对Object类的toString进行重写。

(4) 实例三:重写toString方法

class Person {
	int id;
	String name;
	public Person(int id,String name){
		this.id = id;
		this.name = name;
	}
	@Override
	public String toString(){
		return "编号:"+this.id+"姓名:"+this.name;
		
	}
}
public class Demo2 {
	public static void main(String[] args) {
		Person p = new Person(110,"张三");
		System.out.println(p);
	}
}

运行结果如下图所示:


(5) toString()有何作用?  

重写toString之后,我们直接输出一个对象的时候,就会输出符合我们所需求的格式数据。

2.equals( );

(1) equals(Object obj) 方法用于比较两个对象的内存地址,判断两个对象是否为同一个对象。

(2) 实例一:没有重写equals方法。

①实例:

class Person{
	int id;
	String name;
	public Person(int id,String name){
		this.id = id;
		this.name = name;
	}
}
public class Demo3 {
	public static void main(String[] args){
		Person p1 = new Person(110,"张三");
		Person p2 = new Person(110,"狗蛋");
		System.out.println("p1与p2是同一个对象吗?"+p1.equals(p2));//false
	}
}

②运行结果:


③因为每new一次,Jvm都会开辟一块新的内存空间,所以每new一次,就是一个新的对象。但是在我们现实生活中只要两个人的身份证一致,那么就是同一个人。要实现这种需求也就是父类(Object)的功能无法满足子类的需求,需要重写父类的equals方法。

(3) 实例二:重写equals方法。

①实例:

class Person{
	int id;
	String name;
	public Person(int id,String name){
		this.id = id;
		this.name = name;
	}
	@Override
	public boolean equals(Object obj){
		Person p = (Person)obj;
		return this.id == p.id;
	}
}
public class Demo3 {
	public static void main(String[] args){
		Person p1 = new Person(110,"张三");
		Person p2 = new Person(110,"狗蛋");
		System.out.println("p1与p2是同一个对象吗?"+p1.equals(p2));//true
	}
}

②运行结果:


3.hashCode( );

(1) 该方法返回该对象的哈希码值(我们可以把哈希码就理解成是对象的内存地址);

(2) 实例一:没有重写hashCode方法。

①实例:

class Person{
	int id;
	String name;
	public Person(int id,String name){
		this.id = id;
		this.name = name;
	}
	@Override
	public boolean equals(Object obj){
		Person p = (Person)obj;
		return this.id == p.id;
	}
}
public class Demo3 {
	public static void main(String[] args){
		Person p1 = new Person(110,"张三");
		Person p2 = new Person(110,"狗蛋");
		System.out.println("p1与p2是同一个对象吗?"+p1.equals(p2));//true
		System.out.println("p1的哈希码:"+p1.hashCode());
		System.out.println("p2的哈希码:"+p2.hashCode());
	}
}

②运行结果:


(3) java中的规范:一般我们重写了一个类的equals方法,我们都会重写它的hashCode方法。

原因:因为当我们输出p1和p2是否是同一个对象的时候,结果是true,但是他们的哈希码却不一样,会给别人一种自相矛盾的感觉,既然是一个对象,那为什么哈希码会不同?

(4) 实例二:重写hashCode方法。

①实例

class Person{
	int id;
	String name;
	public Person(int id,String name){
		this.id = id;
		this.name = name;
	}
	@Override
	public boolean equals(Object obj){
		Person p = (Person)obj;
		return this.id == p.id;
	}
	@Override
	public int hashCode(){
		return this.id;
	}
}
public class Demo3 {
	public static void main(String[] args){
		Person p1 = new Person(110,"张三");
		Person p2 = new Person(110,"狗蛋");
		System.out.println("p1与p2是同一个对象吗?"+p1.equals(p2));//true
		System.out.println("p1的哈希码:"+p1.hashCode());
		System.out.println("p2的哈希码:"+p2.hashCode());
	}
}

②运行结果:













<think>好的,我现在需要详细解释Python中的object。首先,我得回忆一下自己对object的理解。object是所有的基,在Python 3中,如果一个没有显式继承其他,它会默认继承object。这可能涉及到新式和旧式的区别,但Python 3已经统一使用新式,所以旧式的问题可能不用多提。 接下来,我需要确认object提供了哪些默认的方法和属性。比如__init__、__str__、__repr__这些魔术方法是否是object的一部分。可能还要提到__dict__属性,它存储对象的属性字典。另外,像__class__属性指向对象的,这些可能都是继承自object的。 然后,object的方法需要具体说明,比如__new__和__init__的作用,__del__作为析构函数。还有比较方法如__eq__、__hash__,以及__getattribute__这样的属性访问方法。可能需要举例子说明覆盖这些方法的影响。 另外,多重继承中object的位置,比如在钻石继承问题中,object作为顶级父如何影响方法解析顺序(MRO)。这部分可能需要用super()函数来说明新式的MRO处理方式。 还要提到使用dir(object)可以查看object的所有属性和方法,帮助用户探索。同时,实例化object本身的情况,比如obj = object(),但这样的实例无法添加属性,因为object没有__dict__,或者可能需要__slots__的解释。 可能需要注意用户在使用object时的一些常见误区,比如重写特殊方法时的注意事项,或者为什么自定义异常最好继承Exception而不是object。这部分需要准确,避免误导。 需要验证一些不确定的点,比如在Python 3中,所有是否确实隐式继承object。是的,Python 3中没有旧式,所以不需要显式继承。但为了代码的兼容性,可能还是建议显式写出。 最后,结构要清晰,分点讲解,可能分为概述、默认方法、重要属性、继承机制、使用示例、注意事项等部分。确保语言简洁,用例子辅助说明,比如展示如何覆盖__str__方法,或者比较两个对象的默认行为。 需要检查是否有错误,例如是否所有都继承objectobject的方法是否默认存在,以及实例化object后的限制是否正确。可能还要提到__slots__和内存优化相关的内容,但可能属于高级话题,简要提及即可。 总结下来,回答需要涵盖object的基础作用、提供的方法和属性、继承机制、使用示例以及注意事项,确保内容准确且易于理解。</think>Python中的`object`是所有的基,在面向对象编程中具有核心地位。以下是对`object`的详细解析: --- ### 一、基础概念 1. **顶级父** - 在Python 3中,所有默认隐式继承自`object`,即使不显式声明。 - 示例: ```python class MyClass: # 等价于 class MyClass(object): pass ``` 2. **新式的统一** - Python 3移除了“旧式”(Python 2中需显式继承`object`才能用新特性),所有均为新式。 --- ### 二、object提供的核心方法 `object`定义了所有的默认行为,以下为关键方法: #### 1. 生命周期方法 - `__init__(self, ...)`:构造方法(默认空实现)。 - `__new__(cls, ...)`:创建实例的静态方法(返回实例对象)。 - `__del__(self)`:析构方法(慎用,因垃圾回收机制不确定)。 #### 2. 对象表示 - `__str__(self)`:返回可读字符串(`print(obj)`时调用)。 - `__repr__(self)`:返回明确的对象描述(调试用,默认实现为名+内存地址)。 #### 3. 比较与哈希 - `__eq__(self, other)`:定义`==`行为(默认比较内存地址)。 - `__hash__(self)`:返回哈希值(若重写`__eq__`,通常需同步重写)。 #### 4. 属性访问 - `__getattribute__(self, name)`:属性访问拦截器。 - `__setattr__(self, name, value)`:设置属性时触发。 --- ### 三、重要属性 1. `__dict__` - 存储对象属性的字典(除非定义了`__slots__`)。 - 示例:`obj.__dict__['name'] = 'Alice'` 等效于 `obj.name = 'Alice'`。 2. `__class__` - 指向对象所属的(如`obj.__class__`返回`MyClass`)。 3. `__doc__` - 的文档字符串(可通过`help(obj)`查看)。 --- ### 四、继承与MRO(方法解析顺序) 1. **多继承中的角色** - `object`位于继承树的顶端,影响方法查找顺序。 - 示例: ```python class A(object): pass class B(A): pass print(B.__mro__) # 输出:(<class 'B'>, <class 'A'>, <class 'object'>) ``` 2. **super()与MRO** - 新式通过C3算法确定方法调用顺序,避免多继承的“菱形问题”。 --- ### 五、使用示例 #### 1. 重写`__str__` ```python class Person: def __init__(self, name): self.name = name def __str__(self): return f"Person: {self.name}" p = Person("Alice") print(p) # 输出:Person: Alice ``` #### 2. 禁止动态添加属性 ```python class Locked(object): __slots__ = ('name',) # 限制只能有name属性 obj = Locked() obj.name = "Alice" obj.age = 20 # 报错:AttributeError ``` --- ### 六、注意事项 1. **避免直接实例化`object`** - `obj = object()`创建的对象无法添加属性(因无`__dict__`)。 2. **特殊方法覆盖需谨慎** - 例如,重写`__eq__`时需保证逻辑一致性,否则可能破坏依赖哈希的容器(如字典、集合)。 3. **继承选择** - 自定义异常应继承`Exception`而非`object`,以兼容异常处理机制。 --- ### 七、探索object 通过`dir(object)`查看所有默认属性和方法: ```python print(dir(object)) # 输出:['__class__', '__delattr__', '__dir__', '__doc__', ...] ``` --- ### 总结 `object`是Python面向对象编程的基石,理解其默认行为和扩展机制是掌握设计的关键。通过重写其方法或利用继承机制,开发者可以灵活定制的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

处女座的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值