(点击跳转即可哦)
JDK常用接口
Object类
全名称:包名.类名
java.lang.Object
在Java中,Object类是Java中所有类的默认父类,无须使用 extends
来定义。
class 声明的类 都有一个父类,Object类
因为Object类是所有类的父类,使用Object引用来接收所有的类型(除了8大基本类型外),参数最高统一化
Object 类中的所有方法子类全都继承下来了
之所以 System.out.println(任意的引用类型)
就是因为都默认调用该类型的toString()
,因为Object类存在toString()
方法
如果想输出当前类中的属性值,我们就要在这个类中覆写
toString()
方法。
Java中引用数据类型之间的相等比较使用 equals
方法,不能使用 “==”,"=="比较的是地址。
equals
方法属于Object类,在Object
类中源代码是:
public boolean equals(Object obj){
retuen (this == obj);
}
此时要比较两个Student类的对象的属性值是否相等,就需要覆写equals
方法。
package EqulasPack;
public class EqualsTest {
public static void main(String[] args) {
Student student1 = new Student("张三",18,"男");
Student student2 = new Student("张三",18,"男");
Student student3 = new Student("李四",18,"男");
System.out.println(student1.equals(student2));
System.out.println(student1.equals(student3));
}
}
class Student{
String name;
int age;
String sex;
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public boolean equals(Object obj){
//1 若当前对象就是 obj
if(this == obj){
return true;
}
//2 此时当前对象和obj指向的对象确实不是一个地址
//若此时obj 指向的对象 本质上和Student 没有关系,直接返回false
if(obj instanceof Student){
//向下转型
Student student = (Student) obj;
return (student.age == this.age
&& this.name.equals(student.name)
&& this.sex.equals(student.sex));
}
return false;
}
}
name属性是String类型,记住JDK的所有类型属性比较都使用equals,并且已经被覆写过了。
啥时候用向下转型?
当一个父类引用实际上指向了一个子类实例时,我们需要调用子类独有的属性或方法时,才会用到向下转型。
Object不仅是所有类(class)的父类
JDK对Object类做了扩展,Object类 可以接收所有引用数据类型的对象(接口,数组,类)。
因此在java中,若一个方法参数或者返回值是Object类型,说明该参数或者返回值可以是任意引用数据类型(接口、数组、类)。
此时除了8大数据类型没法用Object 类来接收以外,所有类型都能使用Object来接收
接口优先原则,当一个场景既可以使用抽象类,也可以使用接口定义时,优先考虑使用接口(更灵活)
JDK 的常用接口:Comparable
java.lang.Comparable
: 当一个类实现了Comparable 接口,表示该类具备了可比较的能力。
package EqulasPack;
import java.util.Arrays;
public class ComparableTest {
public static void main(String[] args) {
Person[] people = new Person[]{
new Person("张三", 29),
new Person("李四", 22),
new Person("王麻子", 33)
};
Arrays.sort(people);
System.out.println(Arrays.toString(people));
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
会报错 ClassCastException
由于Person这个类型是自定义类型,对于编译器来说,不像int 这样大小关系一目了然,到底哪个Person对象大,哪个Person对象小,编译器不知道。
要让Person这个类型具备可比较的能力,也就是让JDK
知道Person对象”谁大谁小“,就需要让Person类实现Comparable
接口,覆写对象方法 compareTo
。
Arrays.sort()
方法的内部实际上就是根据Comparable
接口的compareTo
方法的返回值进行比较的。
@Override
public int compareTo(Object o) {
return 0;
}
当 返回值 > 0 时,表示当前对象this > 传入对象o。
返回值 = 0 时,表示当前对象this = 传入对象o。
返回值 < 0 时,表示当前对象this < 传入对象o。
package EqulasPack;
import java.util.Arrays;
public class ComparableTest {
public static void main(String[] args) {
Person[] people = new Person[]{
new Person("张三", 29),
new Person("李四", 22),
new Person("王麻子", 33)
};
Arrays.sort(people);
System.out.println(Arrays.toString(people));
}
}
class Person implements Comparable{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Object o) {
if(this == o){
return 0;
}
if(o instanceof Person){
Person per = (Person) o;
//此时就是根据年龄的大小比较
// return this.age - per.age;//升序
return per.age - this.age;//降序
}
//报错,抛出异常
throw new IllegalArgumentException("不是Person类型,无法比较!");
}
}
JDK另一个比较重要的接口:克隆接口
java.lang.Cloneable
原对象和新产生对象确实是两个独立的对象,新产生的对象是通过原对象“拷贝”而来的,属性值和原对象完全一致。
要让一个类具备可复制的能力,实现Cloneable接口,覆写clone方法
public interface Cloneable{
}
类似于Cloneable接口,把这种接口称之为“标记”接口,这个接口本身内部没有任何抽象方法,只有打上这个标记的子类才具有克隆的能力。
JVM在运行时会检查所有实现了Cloneable接口的子类,赋予其克隆的能力,clone方法是Object提供的方法。
Animal a1 = new Animal("test");
Animal a2 = a1.clone(); //克隆来的
Animal a3 = new Animal("test"); //new了一个和a1一样的对象
那a2和a3有什么不一样呢?
a1 和a3彼此之间没有任何关系,只是产生a3的时候,属性值恰好等于a1。
a2的产生是依赖于a1产生的。
a3的产生是通过Animal类的构造方法产生的,和a1没有任何关系
在Java中产生一个新对象有两种方式:
1 最普通最常见的,通过构造方法产生对象。
new 类(); -> 当有new关键字,就在堆上开辟该类相应属性的空间,给属性附默认值。
2 通过clone() 产生对象,调用clone时,JVM会开辟与原对象内存大小完全相同的新空间,并将对象中属性的值从原对象中复制一份。
不推荐这种方式产生对象
深拷贝和浅拷贝(了解即可)
浅拷贝:最外层对象确实是由原对象的clone方法产生是新对象,属性值与原对象保持一致,原对象和新对象的内部若包含其他类的引用,这些引用指向的对象是相同的,并没有产生新对象。
深拷贝:最外层对象确实是由原对象的clone方法产生的新对象,属性值与原对象保持一致,原对象和新对象的内部若包含其他类的引用,这些引用指向的对象也是新对象。
要是对大家有所帮助的话,请帮我点个赞吧。