• 【Java SE】抽象类和接口


    作者:✿✿ xxxflower. ✿✿
    博客主页:xxxflower的博客
    专栏:【JavaSE】篇
    语录:⭐每一个不曾起舞的日子,都是对生命的辜负。⭐


    在这里插入图片描述

    1.抽象类

    1.1抽象类的概念

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
    在这里插入图片描述
    像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法(abstract
    method), 包含抽象方法的类我们称为 抽象类(abstract class).

    1.2抽象类语法

    在Java中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。
    在这里插入图片描述
    注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法。

    1.3抽象类的特点

    我们可以先来看一段代码:

    public abstract class Animal {
        public String name;
        public int age;
        abstract void eat();
    }
    class Dog extends Animal{
        Dog(String name,int age){
            this.name = name;
            this.age = age;
        }
        public void eat(){
            System.out.println(name +"吃狗粮!");
        }
    }
    
    class Cat extends Animal{
        Cat(String name,int age){
            this.name = name;
            this.age = age;
        }
        public void eat(){
            System.out.println(name +"吃猫粮!");
        }
    }
    class Test{
        public static void main(String[] args) {
            Dog dog1 = new Dog("旺旺",10);
            Cat cat1 = new Cat("喵喵",5);
            dog1.eat();
            cat1.eat();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    1. 抽象类使用abstract修饰类
    2. 抽象类当中可以包含普通类所能包含的成员
    3. 抽象类和普通类不一样的是,抽象类当中可以包含抽象方法
    4. 抽象方法是使用abstract修饰的,这个方法没有具体的实现
    5. 不能实例化抽象类 new
    6. 抽象类存在的最大的意义就是为了被继承
    7. 如果一个普通类 继承了一个抽象类 此时必须重写抽象类当中的方法。
    8. 如果一个抽象类A继承了一个抽象类B,此时A当中,不需要重写B中的抽象方法。但是如果A再被普通类继承,就需要重写。
    9. 抽象方法不能是私有的。也不能是static的。太满足重写的规则。(即子类的修饰限定符大于等于父类的修饰限定符)
    10. final也不可以,他和abstract是矛盾的
    11. 抽象类当中 可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员。

    很多语法的出现,都是为了能够让程序员更早的发现错误。

    2.接口

    接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口
    接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

    2.1语法

    接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口。

    public interface 接口名称{
    // 抽象方法
    public abstract void method1(); // public abstract 是固定搭配,可以不写
    public void method2();
    abstract void method3();
    void method4();
    // 注意:在接口中上述写法都是抽象方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    提示:

    1. 创建接口时, 接口的命名一般以大写字母 I 开头.
    2. 接口的命名一般使用 “形容词” 词性的单词.

    2.3接口使用

    接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。

    public class 类名称 implements 接口名称{
    // ...
    }
    
    • 1
    • 2
    • 3

    注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。

    2.4接口特性

    1. 使用interface 来修饰接口
    2. 接口当中的成员方法,不能有具体的实现(public)
      1. 抽象方法:默认是public abstract 的方法
      2. JDK1.8开始,允许有可以实现的方法,但是这个方法只能是由default修饰的
      3. 可以实现静态方法。
    3. 成员变量默认是public static final 修饰的
    4. 接口不能被实例化
    5. 子类重写抽象方法,必须加上public
    6. 类和接口之间采用implements 来实现多个接口
    7. 接口中不能有静态代码块和构造方法
    8. 如果你不想实现接口的方法,那么久把这个类定义为抽象类,但是这个类被其他类继承,就必须重写。
    9. 一个类可以实现多个接口。使用implements 用逗号隔开。(可以解决多继承的问题)

    2.7接口使用实例

    package demo1;
    
    import java.util.Arrays;
    
    class Student{
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    public class Test {
        public static void main(String[] args) {
            Student[] students = new Student[3];
            students[0] = new Student("zhang",10);
            students[1] = new Student("huang",20);
            students[2] = new Student("li",30);
    
            Arrays.sort(students);
    
            System.out.println(Arrays.toString(students));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述

    可以看到代码报错了,在比较时要规定一下用什么来比较。姓名,年龄。
    自定义的学生类需要具备可以比较的功能。

    方法一:(根据年龄比较大小
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    总结:如果我们以后自定义的类型,一定要记住,如果要比较大小,那么必须要让这个类具备可以比较的功能,此时可以选择实现接口Compara。

    方法二:(根据姓名比较大小)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    也可以这样写:
    在这里插入图片描述
    方法三:函数冒泡排序法
    在这里插入图片描述

    2.8Clonable接口和深拷贝

    Java 中内置了一些很有用的接口, Clonable 就是其中之一.
    Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常.

    2.8.1Clonable接口

    空接口、标记接口:当前类可以被克隆
    在这里插入图片描述
    在这里插入图片描述
    以下以克隆为例再举一个接口的实例:

    class Person implements Cloneable{
        public int id;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    '}';
        }
    }
    public class Test2 {
        public static void main(String[] args)  throws CloneNotSupportedException{
            Person person = new Person();
            Person person2 = (Person)person.clone();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这就是浅拷贝。

    2.8.2深拷贝

    
    class Money implements Cloneable{
        public double m = 66.66;
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    class Person implements Cloneable{
        public int id;
        public Money money = new Money();
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Person tmp = (Person)super.clone();
            tmp.money = (Money)this.money.clone();
            return tmp;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    '}';
        }
    }
    public class Test2 {
        public static void main(String[] args)  throws CloneNotSupportedException{
            Person person = new Person();
            Person person2 = (Person)person.clone();
            person2.money.m =8888;
            System.out.println("person:"+person.money.m);
            System.out.println("person2 :"+person2.money.m);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    图解代码:
    在这里插入图片描述
    在这里插入图片描述

    2.9抽象类和接口的区别

    核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.
    抽象类存在的意义是为了让编译器更好的校验
    在这里插入图片描述

    3.Object类

    Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收。

    3.1 获取对象信息

    如果要打印对象中的内容,可以直接重写Object类中的toString()方法。

    3.2对象比较equals方法

    在Java中,== 进行比较时:
    a.如果左右两侧是基本类型变量,比较的是变量中值是否相同
    b.如果
    左右两侧是引用类型变量,比较的是引用变量地址是否相同
    c.如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的

    3.3hashcode方法

    涉及数据结构,后面我们再深入学习
    hashcode方法源码:

    public native int hashCode();

    该方法是一个native方法,底层是由C/C++代码写的。我们看不到。

    结论:
    1、hashcode方法用来确定对象在内存中存储的位置是否相同
    2、事实上hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。

  • 相关阅读:
    第2章 MyBatis的核心配置
    Educational Codeforces Round 125 (Rated for Div. 2) CD题解
    1. 树的建立与基本操作
    使用Python进行数据分析与可视化
    简单工厂和工厂方法模式
    SpringCloud中Turbine 1.X版本BUG
    简单三步走搞定动态规划难题,记好这三板斧,动态规划就不难
    2011--利用数学知识解题
    ATF启动(三):BL2
    7-13 计算圆周率
  • 原文地址:https://blog.csdn.net/qq_61138087/article/details/126807483