- Object类
- Object类的好处
- equals()方法
- 重写equlas()方法
- Object总结
- JDK内置常用接口
- Comparable接口
- 重写compareTo()
- Cloneable接口
- 重写clone()方法
- 深浅拷贝
object类是所有类的父类,无需使用extends来定义,声明的每个类都默认继承Object类.
Object类的好处- Object是所有类的父类,可以接受任意类型,是参数最高统一化.
Object obj1 = new Dog(); Object obj2 = "abc"; Object obj3 = new int[10];
- Object类的所有方法,子类都继承了.
为什么System类可以打印所有类型的数据,是因为Object里面有toString()方法.打印时会默认调用toString()方法.
Animal dog = new Dog();
System.out.println(dog);
System.out.println(123);
System.out.println("abc");
打印结果:
com.Dog@14ae5a5 123 abc
如果我们想输出对象中的属性值,那我们就在该对象中覆写toString()方法.
public class Dog {
public String name="狗";
public int age =20;
@Override
public String toString() {
return "name"+name +","+ "age"+age;
}
}
//Animal dog = new Dog();
//System.out.println(dog);
name狗,age20equals()方法
如果我们要比较两个引用类型是否相等,我们使用equals()方法.
不能使用"=="比较,因为它比较的是地址.
Student s1 = new Student(); Student s2 = new Student(); Student s3 = s1; System.out.println(s1==s2);//false System.out.println(s1==s3);//true
false true
如果我们没有重写equals()方法,那运行时还是会默认调用Object中的equals()方法,Object中的equals()方法比较的还是地址,所以得到的结果和使用"=="相同.
Student s1 = new Student(); Student s2 = new Student(); Student s3 = s1; System.out.println(s1.equals(s2)); System.out.println(s1.equals(s3));
false true
这是Object中的equals()方法.
为什么要重写equals()方法?
如果我们不重写equals(),那么引用类型比较的是地址.如果我们想比较引用类型的成员变量呢,这时候就必须重写equals().
Student s1 = new Student("小明",18);
Student s2 = new Student("小华",20);
Student s3 = new Student("小明",18);
//我们要比较三个学生的成绩,我们就需要重写equals()方法
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
//重写equals方法
public boolean equals(Object obj) {
//如果传入的是同一个对象
if (this == obj) {
return true;
}
//传入的变量不是同一对象
if (obj instanceof Student) {
//Object obj = new Student();
//obj是Object类型,因为Object中没有成员变量name和age,所以必须向下转型
Student stu = (Student) obj;
// //这里的equal()方法调用的是String里面的,已经重写过了
return this.age == stu.age && this.name.equals(stu.name);
}
return false;
}
打印结果:
false trueObject总结
什么时候会用到向下转型?
当一个Object类指向一个子类实例时,我们需要调用子类独有的属性和方法时,这时候就必须用到向下转型
我们要比较两个引用类型的什么属性,就在equals()里面重写.
Object可以接收各种引用类型,比如接口,数组,类等
但是Object 不能接收8大基本类型,所以包装类应运而生~~
JDK内置常用接口接口优先原则:当一个场景即可以使用抽象类,又可以使用接口定义时,优先使用接口(更灵活).
Comparable接口当一个类实现了Comparable接口,那么该类就具备了可比较的能力.
public static void main(String[] args) {
int[] data = new int[]{1,2,3};
//调用sort进行排序
Arrays.sort(data);
System.out.println(Arrays.toString(data));
如果我们自定义一个类型.
public static void main(String[] args) {
Student[] s = new Student[]{
new Student("小明", 80),
new Student("小华", 90),
new Student("小兰", 100)
};
//排序
Arrays.sort(s);
System.out.println(Arrays.toString(s));
}
}
这是因为Student是一个自定义类型,对于编译器来说,它不像int一样大小一目了然,到底哪个Student大,哪个Student小,JDK无从得知,为了让Student具备可比较的能力,此时就必须让Student类中实现Comparable接口,覆写接口中的compareTo方法.
public class Student implements Comparable {
public String name;
public int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return name + ":" + score;
}
@Override
public int compareTo(Object o) {
if (this == o) {
return 0;
}
if (o instanceof Student) {
//o是Student对象
//此时的o是Object类型,所以需要向下转型
Student stu = (Student) o;
//比较分数的大小
return this.score - stu.score;
}
throw new IllegalArgumentException();
}
public static void main(String[] args) {
// int[] data = new int[]{1,2,3};
// //调用sort进行排序
// Arrays.sort(data);
// System.out.println(Arrays.toString(data));
//s是一个Student类型的数组
Student[] s = new Student[]{
new Student("小华", 90),
new Student("小明", 80),
new Student("小兰", 100)
};
Arrays.sort(s);
System.out.println(Arrays.toString(s));
}
public static void sort(Comparable[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j].compareTo(arr[j + 1]) > 0) {
Comparable temp = null;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
Arrays.sort方法实际还是根据Comparable接口里面的compareTo方法的返回值进行比较的.
Cloneable接口克隆接口:原对象和新对象是两个独立的个体,新对象是通过原对象拷贝而来的,属性值和原对象完全相同.
重写clone()方法为了让一个类具有复制的能力,需要implements Cloneable接口,覆写clone()方法.
public class Animal implements Cloneable {
public String name;
public Animal(String name) {
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
Animal newAnimal = null;
newAnimal = (Animal) super.clone();
return newAnimal;
}
public static void main(String[] args) throws CloneNotSupportedException {
Animal animal1 = new Animal("狗");
//调用clone()克隆一个animal1
Animal animal2 = (Animal) animal1.clone();
//animal1和animal2为不同的对象
System.out.println(animal1 == animal2);
System.out.println(animal2.name);
//如果我们再创建一个animal3,name="狗",那么这个animal2和animal3没有任何关系
//只是恰好同名而已
Animal animal3 = new Animal("狗");
}
}
类似Comparable接口,这种接口被称为"标记"接口,这种接口内本身没有任何抽象方法,只有打上了这个标记的子类,才具备克隆的能力.
clone方法再克隆的时候不会调用无参构造方法.
public Animal(){
System.out.println("Animal的无参构造");
}
Animal animal1 = new Animal();
Animal anima2 = animal1.clone();
深浅拷贝



