「JavaSE」抽象类&接口3

个人主页:Ice_Sugar_7
所属专栏:快来卷Java啦
欢迎点赞收藏加关注哦!

抽象类&接口3

  • Clonable 接口和深拷贝
    • 浅拷贝和深拷贝
  • Object类
  • 抽象类和接口的区别
  • 总结

Clonable 接口和深拷贝

Object 类中存在一个 clone 方法,调用这个方法可以创建一个对象的拷贝
要调用 clone 方法,需要先实现 Clonable 接口,否则就会抛出 CloneNotSupportedException 异常(不支持克隆异常)

浅拷贝和深拷贝

Cloneable拷贝出的对象是一份浅拷贝,下面用一个例子来解释一下:

class Money implements Cloneable{
    public double m = 19.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Person implements Cloneable{
    public String name;
    public int age;

    public Money money = new Money();  //实例化一个Money对象

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

	@Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person("张三",20);
        Person person2 = (Person)person.clone();//clone
        System.out.println("person "+person.money.m);
        System.out.println("person2 "+person2.money.m);
        System.out.println("===========");
        person.money.m = 100;
        //观察将m修改为100之后两个对象的m是多少
        System.out.println("person "+person.money.m);
        System.out.println("person2 "+person2.money.m);
    }
}

「JavaSE」抽象类&接口3_第1张图片
可以看到两个对象的m都变为100.0,说明person、person2的money都指向同一个m
「JavaSE」抽象类&接口3_第2张图片

由此我们可以总结浅拷贝的特征:
浅拷贝会创建一个新对象,但是对于引用类型的字段,只复制了引用,而不是复制引用指向的对象

而深拷贝就会复制引用所指对象
现在想实现深拷贝,我们就要给money也拷贝一份,需要把Person的clone方法改一下:

    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();  //对原对象进行克隆
        tmp.money = (Money) this.money.clone();  //克隆对象中引用类型所指的对象
        return tmp;
    }

「JavaSE」抽象类&接口3_第3张图片
「JavaSE」抽象类&接口3_第4张图片
「JavaSE」抽象类&接口3_第5张图片
深拷贝后,再修改person的m,就不会影响person2的了
「JavaSE」抽象类&接口3_第6张图片


Object类

Object是Java默认提供的一个类,Java中所有类默认继承Object父类。即所有类的对象都可以使用Object的引用进行接收,举个例子:

    public static void func(Object obj) {
        System.out.println(obj);
    }

    public static void main(String[] args) {
        func(new Student("Sugar",90));
        func(new Money());
    }

「JavaSE」抽象类&接口3_第7张图片
Object类中也有一些定义好的方法,本文讲解其中的 toString( ) 和 equals( )
「JavaSE」抽象类&接口3_第8张图片

  1. toString( )
    如果要打印对象中的内容,就需要重写Object类中的toString()方法,不然会打印出它的地址(内存地址的字符串表示形式)
// Object类中的toString()方法实现:
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
  1. equals( )
    我们常见的==就可以实现比较,它在比较时:
    如果它左右操作数是基本类型变量,比较的是变量中值是否相同
    如果左右两侧是引用类型变量,则比较引用变量地址是否相同

要比较对象的内容是否相等,那就要用到equals方法,但是需要进行重写,因为它默认按地址进行比较的

// Object类中的equals方法
public boolean equals(Object obj) {
	return (this == obj); // 使用引用中的地址直接来进行比较
}
	//Student类中重写equals,用idea的generate可以直接生成
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return grade == student.grade;
    }

    public static void main(String[] args) {
        Student student1 = new Student("砂糖橘",98);
        Student student2 = new Student("zs",98);
        boolean ret = student1.equals(student2);
        System.out.println(ret);  //运行结果为true
    }

抽象类和接口的区别

抽象类和接口都是 Java 中多态的常见使用方式,都需要重点掌握,同时也需要了解二者之间的区别
核心区别

  • 抽象类中可以包含普通方法和字段,这样的普通方法和字段可以被子类直接使用(不必重写)
  • 而接口中不能包含普通方法,子类必须重写所有的抽象方法

「JavaSE」抽象类&接口3_第9张图片


总结

  1. Cloneable接口的clone方法可以实现浅拷贝,如果要实现深拷贝,那么让需要对对象中的引用类型进行拷贝
  2. Java中默认Object类是所有类的父类。Object中已经实现了一些方法,子类通过重写这些方法可以实现相应的功能
  3. 注意区分抽象类和接口

你可能感兴趣的:(快来卷Java啦,java,开发语言)