• JAVASE语法零基础——抽象类和接口


    Java系列文章目录


    在这里插入图片描述

    Write once,Runanywhere.🔥🔥🔥

    💥 💥 💥如果你觉得我的文章有帮助到你,还请【关注➕点赞➕收藏】,得到你们支持就是我最大的动力!!!
    💥 💥 💥

    版权声明:本文由【马上回来了】原创、在CSDN首发、需要转载请联系博主。
    版权声明:本文为CSDN博主「马上回来了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

    在这里插入图片描述

    🚀🚀🚀 新的知识开始喽🚀🚀🚀
    在这里插入图片描述



    1.抽象类

    抽象类概念:在面向对象的思想里,对象都是通过类来描绘的,但是反过来,不是所有的类都能用来描绘对象,当一个类包含的信息不足以描绘一个对象时,这样的类就是抽象类。
    比如上一篇多态文章里最后那个画图形的代码:
    在这里插入图片描述
    因此父类Shape里的draw方法可以不用写得具体,因为draw方法实际上总是调用子类重写的draw方法,所以可以将draw方法设计成抽象方法:用abstract修饰的方法,没有具体的实现操作,让子类进行重写。而包含抽象方法的类就是抽象类,也得用abstract修饰。
    在这里插入图片描述

    //被abstract修饰的类为抽象类
    abstract class Shape{
        //被abstract修饰的方法为抽象方法 抽象方法---一个方法没有具体的实现
        public abstract void draw();
    }
    //抽象类是用来被继承的,被继承的抽象类如果包含了抽象方法,那么抽象方法必须重写
    class Flower extends Shape{
    //重写抽象方法
        @Override
        public void draw() {
            System.out.println("💐");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    再看下面这张图,就可以很好的了解抽象类了:
    在这里插入图片描述

    2.抽象类语法

    在Java中,一个类如果被 abstract 修饰称为抽象类抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。
    1.抽象类也是类,内部可以包含普通方法、属性、构造方法。

    //被abstract修饰的类为抽象类
    abstract class Shape{
        //成员属性
        public int num;
    //构造方法
        public Shape(int num) {
            this.num = num;
        }
        //普通方法
    public void fun(){
        System.out.println("普通方法");
    }
        //被abstract修饰的方法为抽象方法 抽象方法---一个方法没有具体的实现
        public abstract void draw();
    }
    //抽象类是用来被继承的,被继承的抽象类如果包含了抽象方法,那么抽象方法必须重写
    class Flower extends Shape{
        public Flower(int num) {
            super(num);
        }
    
        //重写抽象方法
        @Override
        public void draw() {
            System.out.println("💐");
        }
    }
    
    public class demo1 {
    
    }
    
    • 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

    在这里插入图片描述
    2.抽象类不能实例化对象,抽象类必须用来被继承并且继承后子类要重写父类中的抽象方法。
    在这里插入图片描述

    3.否则子类也是抽象类,必须要使用 abstract 修饰。

    //被abstract修饰的类为抽象类
    abstract class Shape{
        //成员属性
        public int num;
    //构造方法
        public Shape(int num) {
            this.num = num;
        }
        //普通方法
    public void fun(){
        System.out.println("普通方法");
    }
        //被abstract修饰的方法为抽象方法 抽象方法---一个方法没有具体的实现
        public abstract void draw();
    }
    abstract class Smile extends Shape{
        public Smile(int num) {
            super(num);
        }
    //不用重写抽象方法
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3.如果是多个抽象类多被重继承之后再被非抽象类继承,则需要重写所有继承的抽象类的所有抽象方法。

    //被abstract修饰的类为抽象类
    abstract class Shape{
        //成员属性
        public int num;
    //构造方法
        public Shape(int num) {
            this.num = num;
        }
        //普通方法
    public void fun(){
        System.out.println("普通方法");
    }
        //被abstract修饰的方法为抽象方法 抽象方法---一个方法没有具体的实现
        public abstract void draw();
    }
    abstract class Smile extends Shape{
        public Smile(int num) {
            super(num);
        }
        abstract public void draw1();
    
    }
    class Star extends Smile{
        public Star(int num) {
            super(num);
        }
    
        @Override
        public void draw() {
            System.out.println("😊");
        }
    
        @Override
        public void draw1() {
            System.out.println("🎇");
    
        }
    }
    
    • 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
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述
    4.抽象方法不能被 private、final、static修饰,因为被这些关键字修饰的方法不能被重写。注意:抽象方法没有加修饰访问限定符,默认是public。
    5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
    6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量

    使用抽象类来实现多态的代码:

    //被abstract修饰的类为抽象类
    abstract class Shape{
        //成员属性
        public int num;
    //构造方法
        public Shape(int num) {
            this.num = num;
        }
        //普通方法
    public void fun(){
        System.out.println("普通方法");
    }
        //被abstract修饰的方法为抽象方法 抽象方法---一个方法没有具体的实现
        public abstract void draw();
    }
    class Flower extends Shape{
        public Flower(int num) {
            super(num);
        }
    
        //重写抽象方法
        @Override
        public void draw() {
            System.out.println("💐");
        }
    }
    
    public class demo1 {
        public static void drawMap(Shape shape){//向上转型
            shape.draw();
        }
        public static void main(String[] args) {
            Flower flower = new Flower(1);
            drawMap(flower);
    
        }
    
    
    • 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
    • 35
    • 36
    • 37

    运行结果:
    在这里插入图片描述

    3.抽象类的作用

    抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法。
    有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?
    确实如此, 但是使用抽象类相当于多了一重编译器的校验。
    在这里插入图片描述

    使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题。

    4.接口

    在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
    接口比抽象类还要抽象(接口没有实例代码、静态代码块、构造方法),接口也不能实例化对象,也是通过其他类来实现接口然后重写接口里的抽象方法。

    5.接口语法

    分为三类:

    1.结构实现方面

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

    interface IShape{
    void draw();
    }
    
    • 1
    • 2
    • 3

    提示:

    1. 创建接口时, 接口的命名一般以大写字母 I 开头。
    2. 阿里编码规范中约定,接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性。

    1.2.接口不能直接使用,必须要有一个"实现类"来"实现"该接口(通过关键字impls),实现接口中的所有抽象方法。

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

    注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。
    1.3. 接口类型是一种引用类型,但是不能直接new接口的对象
    在这里插入图片描述

    1.4.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
    在这里插入图片描述

    1.5.如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
    在这里插入图片描述
    再被普通类继承则需要重写上面抽象类和接口的抽象方法:
    在这里插入图片描述

    1.6.一个接口可以引用具体实现类,向上转型。
    在这里插入图片描述

    interface IShape{
    
        int a = 10;
        public static final int b = 10;//成员变量默认
    void draw();
    //    void fun();
    //    public abstract  void fun1();//抽象方法默认
    
        default public void fun2(){//default 方法 可以有具体实现,可以不被重写
    
        }
        static public void fun3(){//static方法可以有具体实现,不能被重写
    
        }
    }
    abstract class T implements IShape{
        //抽象类可以不重写接口里的抽象方法
        abstract public void t();
    }
    class A extends T{
    
        @Override
        public void draw() {
    
        }
    
        @Override
        public void t() {
    
        }
    }
    
    class Flower implements IShape{
        @Override
        public void fun2(){
    
        }
        @Override
        public void draw() {
            System.out.println("💐");
        }
    }
    public class Test {
        public static void drawMap(IShape shape){//向上转型
            shape.draw();
        }
        public static void main(String[] args) {
            drawMap(new Flower());
        }
    }
    
    
    • 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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    2.方法方面

    2.1.接口中每一个方法默认都是public的抽象方法不能有具体的实现, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)。
    2.2. 重写接口中方法时,因为接口里的抽象方法是public abstract修饰,所以实现接口类里重写抽象方法时不能使用default访问权限修饰
    2.3. 如果要想接口里的方法有具体实现类,则用default修饰(jdk8以=以后才有)、static修饰,default修饰的方法可以不重写,而被static修饰的方法不能被重写。

    3.成员属性方面

    3.1.接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量。

    5.实现多个接口

    在java中类和类之间是单继承的,一个类只能继承一个父类,即java中不支持多继承,但是一个类可以实现多个接口
    只能先继承然后再实现多个接口
    下面通过一动物来掩饰:

    //抽象类
    abstract class Animal{
        public String name;
        public int age;
    
        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public abstract void eat();
    }
    //跑
    interface IRuning{
        void run();
    }
    //飞
    interface IFlying{
        void fly();
    }
    //游泳
    interface ISwimming{
        void swimming();
    }
    class Dog extends Animal implements IRuning,ISwimming{
        public Dog(String name, int age) {
            super(name, age);
        }
    
        @Override
        public void eat() {
            System.out.println(name+"正在吃狗粮");
        }
    
        @Override
        public void run() {
            System.out.println(name+"正在四条腿跑");
        }
    
        @Override
        public void swimming() {
            System.out.println(name+"正在狗刨");
    
        }
    }
    class Bird extends Animal implements IRuning,IFlying{
        public Bird(String name, int age) {
            super(name, age);
        }
    
        @Override
        public void eat() {
            System.out.println(name+"正在吃鸟粮");
    
        }
    
        @Override
        public void run() {
            System.out.println(name+"正在两条细腿跳着跑");
        }
    
        @Override
        public void fly() {
            System.out.println(name+"两只小翅膀正在飞");
    
        }
    }
    class Duck extends Animal implements IRuning,IFlying,ISwimming{
        public Duck(String name, int age) {
            super(name, age);
        }
    
        @Override
        public void eat() {
            System.out.println(name+"鸭子正在吃鸭粮");
        }
    
        @Override
        public void run() {
            System.out.println(name+"两只大脚掌正在跑");
        }
    
        @Override
        public void fly() {
            System.out.println(name+"两只大翅膀在飞");
        }
    
        @Override
        public void swimming() {
            System.out.println(name+"两只大脚掌在游泳");
    
        }
    }
    public class Test {
       //抽象类引用
        public static void eat(Animal animal){
            animal.eat();
        }
        //接口类引用
        public static void run(IRuning iRuning){
            iRuning.run();
        }
        public static void fly(IFlying iFlying){
            iFlying.fly();
        }
        public static void swim(ISwimming iSwimming){
          iSwimming.swimming();
        }
        public static void main(String[] args) {
            eat(new Dog("边牧",4));
            eat(new Bird("鹦鹉",1) );
            eat(new Duck("唐老鸭",15));
            System.out.println("======================");
            run(new Dog("边牧",4));
            run(new Bird("鹦鹉",1) );
            run(new Duck("唐老鸭",15));
            System.out.println("======================");
            fly(new Bird("鹦鹉",1) );
            fly(new Duck("唐老鸭",15));
            System.out.println("=======================");
            swim(new Dog("边牧",4));
            swim(new Duck("唐老鸭",15));
        }
    }
    
    • 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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    在这里插入图片描述
    在这里插入图片描述

    运行结果:
    在这里插入图片描述
    上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口。
    继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性

    鸭子也是一种动物, 既能跑, 也能游, 还能飞

    这样设计有什么好处呢? 时刻牢记多态的好处, 让程序员忘记类型.。有了接口之后, 类的使用者就不必关注具体类型,而只关注某个类是否具备某种能力。
    比如狗、鸟、鸭子都能跑。

    6.接口的继承

    在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的。
    接口可以继承一个接口, 达到复用的效果.,使用 extends 关键字。

    interface IA{
        void func1();
    }
    interface IB{
        void func2();
    }
    //接口间的继承----拓展接口功能
    interface IC extends IA , IB {接口相当于有了接口IA和接口IB的功能
        void func3();
    }
    class T implements IC{
        @Override
        public void func1() {
            System.out.println("重写接口IA里的抽象方法");
        }
    
        @Override
        public void func2() {
            System.out.println("重写接口IB里的抽象方法");
    
        }
    
        @Override
        public void func3() {
            System.out.println("重写接口IC里的抽象方法");
    
        }
    }
    public class Test0 {
    }
    
    
    • 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

    🌏🌏🌏今天的你看懂这里又学到了很多东西吧🌏🌏🌏

    在这里插入图片描述

    🌔 🌔 🌔下次见喽🌔 🌔 🌔
    在这里插入图片描述

  • 相关阅读:
    零基础学摄影 || 曝光三要素
    【Vue全家桶】新一代的状态管理--Pinia
    吃透这份高并发/调优/分布式等350道面试宝典,已涨30k
    Android移动应用开发之Button按钮与事件
    使用c++实现简易线程池
    《精通特征工程》学习笔记(6):非线性特征化与k-均值模型堆叠
    代码随想录算法训练营第60天(动态规划17● 647. 回文子串 ● 516.最长回文子序列 ● 动态规划总结篇
    Python实现Catboost分类模型(CatBoostClassifier算法)项目实战
    赫夫曼树的创建(思路分析)
    消息队列的七种经典应用场景
  • 原文地址:https://blog.csdn.net/m0_62160964/article/details/125545535