【Java学习—(14)认识Object类、JDK常用接口】接Java学习(13)

(点击跳转即可哦)

java学习专栏

LeetCode刷题专栏


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方法产生的新对象,属性值与原对象保持一致,原对象和新对象的内部若包含其他类的引用,这些引用指向的对象也是新对象。



要是对大家有所帮助的话,请帮我点个赞吧。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值