前言:
Java中有个"祖先",就是Object类,这个任意类的父类,为什么这样说呢?
接下来我们一起探究一下!
Object类:
Object这个类是编译器给我们提供的,那么这个类放在什么地方呢?
就在这个地方!
Object类里面有好多成员方法我们都可以用,而且挺常见。
为什么说Object类是所有类的父类呢?
因为我们每次定义完一个类之后,如果没有继承父类,其实编译器会默认继承一个Object类,就算如果我们的类中继承了一个父类,那么,编译比会在父类的基础上在继承一个父类,也就是父类的父类!
这就是Object类中的所有方法,当然我们也可以进行多态,也就是重写Object类中的方法,然后通过父类的引用接收子类对象,达到我们想要的结果。
class person{} class student{}public class Test1 { public static void main(String[] args) { function(new person()); function(new student()); } public static void function(Object obj){ System.out.println(obj); } }打印结果:
这个打印结果是什么意思呢?
这个打印结果前面是两个类的所在路径,@后面是哈希值,也可以理解为这两个类所在的地址。
那么,我可不可以在打印的时候不去这样打印,我想要自定义打印的结果。
也许是可以的。
toString方法:
在Object类中提供了一个toString方法,这个方法就可以打印出我们想要的内容,我们只需要重写toString方法:
class person{
@Override
public String toString() {
return "这是一个人";
}
}
class student{
@Override
public String toString() {
return "这是一个学生";
}
}
如上我重写了toString方法,此时再次在main方法中打印:
发现真的如我们所愿打印!
所以说其实System.out.print()这个方法接见调用的是Object类中的toString方法打印!
equals方法:
这个方法是用来比较两个字符串是不是一样的,一样的话返回true,不一样的话返回false,当然这个方法也可以重载,达到我们想要的效果:
如果此时我i详设计一个判断两个人年龄和姓名是否一样的方法,此时就可以重写该方法:
class Person{
int age;
String name;
@Override
public boolean equals(Object obj) {
Person person = (Person) obj;
return this.age == person.age &&this.name.equals(person.name);
}
}
测试:
public class Test1 {
public static void main(String[] args) {
Person person1 = new Person(13, "liucheng");
Person person2 = new Person(13, "liuchen");
if(person1.equals(person2)){
System.out.println("两个人一样");
}else{
System.out.println("两个人不一样");
}
}
}
hashCode方法:
public class Test1 {
public static void main(String[] args) {
Person person1 = new Person(13, "liucheng");
Person person2 = new Person(13, "liucheng");
System.out.println(person1.hashCode());
System.out.println(person2.hashCode());
}
}
注意事项:两个对象的 hash 值不一样
此时重写哈希方法:
public int hashCode() {
return Objects.hash(name, age);
}
}
此时,如果两个人年龄和名字相同哈希值应该也是一样的:
clone方法:
clone方法也是一个很重要有用的方法,但是该方法的使用,必须实现一个接口——Cloneable接口,不然在调用clone方法时会报错!
class Money implements Cloneable{
public double a = 9.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
private String name;
public Money m;
public Person(String name){
this.name = name;
m = new Money();
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Test2 {
public static void main(String[] args) throws CloneNotSupportedException{
Person person = new Person("lili");
Person person1 = (Person) person.clone();
//修改之前
System.out.println(person.m.a);
System.out.println(person1.m.a);
//修改之后
person.m.a = 3;
System.out.println(person.m.a);
System.out.println(person1.m.a);
}
}
我们发现打印的结果正合我们意!
但是,我们如果仔细想想,我拷贝结束之后,为什么我改变原来person里面成员的值,为什么会影响我新拷贝的person对象里面成员的值呢?
他们拷贝结束之后难道不是相互独立的吗?
画图解释:
此时这种拷贝被成为浅拷贝,也就是只拷贝了person类,但是里面的内容其实并没有被拷贝出来,所以想要一起连着内容都拷贝出来,应该进行深拷贝!!
深拷贝:
首先我们想要的效果是这样!
修改代码如下:
@Override
protected Object clone() throws CloneNotSupportedException {
Person tmp = (Person) super.clone();
tmp.m = (Money) this.m.clone();
return tmp;
}
此时就完成了深拷贝: