美文网首页
【JAVA学习笔记】抽象类与接口

【JAVA学习笔记】抽象类与接口

作者: Geekero | 来源:发表于2021-04-21 22:25 被阅读0次

    学习自华为开发者学院陈璇老师的JAVA系列课程

    一、抽象类

    1. 没有抽象构造方法,也没有抽象静态方法
    2. 抽象类中可以有非抽象的构造方法,创造子类的实例时可能调用

    例如:
    Base.java

    //父类
    public abstract class Base {
        public Base(){
            System.out.println("父类(抽象类)的构造方法");
        }
    }
    

    Son.java

    //子类
    public class Son extends Base{
        public Son() {
            System.out.println("子类的构造方法");
        }
    
        public static void main(String[] args) {
            Son son = new Son();
            Base son1 = new Son();
        }
    }
    

    输出

    父类(抽象类)的构造方法
    子类的构造方法
    父类(抽象类)的构造方法
    子类的构造方法
    

    二、接口

    2.1 JDK8之前的接口:

    接口只允许有抽象的方法



    JDK8之前的接口特性:



    总结

    MyInterface1.java

    public interface MyInterface1{
        //接口不能有构造方法,也不能被实例化
        //静态常量: 接口中的变量,必须是public static final, 且要显示得初始化
        //public static final double PI = 3.14;
        //等同于
        double PI = 3.14;
    
        //JDK8之前,接口中只能有public abstract的方法
        public abstract void m1();
    
        //等同于这样声明 public abstract int m2()
        int m2();
    }
    

    MyInterface2.java

    public interface MyInterface2 {
        public abstract void m3();
    }
    

    Sub1.java

    //实现类必须实现接口中的全部抽象方法,除非实现类也是一个抽象类
    public class Sub1 implements MyInterface1, MyInterface2 {
        public void m1() {
            System.out.println("实现类实现了接口中的m1方法");
        }
    
        public int m2() {
            return 0;
        }
    
        public void m3() {
            System.out.println("实现类实现了第二个父接口中的m3方法");
        }
    }
    

    Test.java

    public class Test {
        public static void main(String[] args) {
            //接口可以当做类型来使用
            System.out.println(MyInterface1.PI);
            MyInterface1 m = new Sub1();
            m.m1();
    
            MyInterface2 m2 = new Sub1();
        }
    }
    

    2.1 JDK8新增的接口特性:



    应用场景:



    Father.java:
    package cn.com.myinterface.pac2;
    
    public abstract class Father {
        public void m5() {
            System.out.println("抽象类Father中的m5方法");
        }
    }
    

    MyInterface1.java

    package cn.com.myinterface.pac2;
    
    public interface MyInterface1 {
        //接口不能有构造方法,也不能被实例化
        //静态常量: 接口中的变量,必须是public static final, 且要显示得初始化
        //public static final double PI = 3.14;
        //等同于
        double PI = 3.14;
    
        //JDK8之前,接口中只能有public abstract的方法
        public abstract void m1();
    
        //等同于这样声明 public abstract int m2()
        int m2();
    
        //JDK8之后,接口中可以定义default默认方法了
        default void m3() {
            System.out.println("接口MyInterface1中的默认方法m3");
        }
    
        default void m5() {
            System.out.println("接口MyInterface1中的默认方法m5");
        }
    
        //JDK8之后,接口中可以定义static静态方法
        static void m6() {
            //等同于public static void m6()
            System.out.println("接口MyInterface1中的静态方法m6");
        }
    
        static void m7() {
            //等同于public static void m7()
            System.out.println("接口MyInterface1中的静态方法m7");
        }
    }
    

    MyInterface2.java

    package cn.com.myinterface.pac2;
    
    public interface MyInterface2 {
        default void m3() {
            System.out.println("接口MyInterface2中的默认方法m3");
        };
    }
    

    Sub1.java

    package cn.com.myinterface.pac2;
    
    //实现类必须实现接口中的全部抽象方法,除非实现类也是一个抽象类
    public class Sub1 extends Father implements MyInterface1, MyInterface2{
        public void m1() {
            System.out.println("实现类实现了接口中的m1方法");
        }
    
        public int m2() {
            return 0;
        }
    
        /*当实现类的两个父接口中有同样的默认方法时:
        * 解决方案2:子类重写覆盖掉父接口的默认方法m3*/
        //public void m3() {
        //     System.out.println("sub类重写覆盖掉父接口的默认方法m3");
        // }
    
        /*当实现类的两个父接口中有同样的默认方法时:
         * 解决方案1:子类通过super指定调用哪个父接口的默认方法*/
        public void m3() {
            MyInterface1.super.m3();
        }
    }
    

    Test.java

    package cn.com.myinterface.pac2;
    
    public class Test {
        public static void main(String[] args) {
            //接口可以当做类型来使用
            //默认方法可以被继承,通过实例调用
            System.out.println(MyInterface1.PI);
            MyInterface1 m = new Sub1();
            m.m3();
            MyInterface2 m2 = new Sub1();
            m2.m3();
    
            Sub1 s = new Sub1();
            s.m3();
    
            //采用类优先的方法,优先继承抽象类中m5方法
            m.m5();
            s.m5();
    
            //静态方法可以被接口直接调用
            MyInterface1.m6();
        }
    }
    

    三、面向接口编程

    程序设计时:

    1. 关心实现类有何能力,而不关心实现细节
    2. 面向接口的约定,而不考虑接口的具体实现

    案例1
    USB.java

    //USB接口:描述连接计算机和外部设备的串口总线标准,定义一种输入输出接口的技术规范
    public interface USB {
        //USB接口并不实现具体功能,通过抽象方法来定义一种数据输入输出规范和标准,能力
        void service();
    }
    

    USBdisk.java

    //满足USB标准的U盘
    public class USBdisk implements USB{
        public void service() {
            System.out.println("连接USB口,开始传输数据");
        }
    }
    

    USBfan.java

    //满足USB标准的风扇
    public class USBfan implements USB{
        public void service() {
            System.out.println("连接USB口,获得电流,风扇开始转动");
        }
    }
    

    Test.java

    //使用接口
    public class Test {
        public static void main(String[] args) {
            //USB风扇
            USB uFan = new USBfan();
            uFan.service();
    
            //USB标准U盘
            USB uDisk = new USBdisk();
            uDisk.service();
        }
    }
    

    总结


    image.png

    3.1 面向接口编程的步骤

    step01.分析类和接口



    step02.画类图



    进行类的设计

    step04.转换为代码
    Door.java

    //门:抽象方法 开门 关门
    public abstract class Door {
        public abstract void open();
        public abstract void close();
    }
    

    DoorBell.java

    //门铃:拍照存储
    public interface DoorBell {
        void takePictures();
    }
    

    Lock.java

    //锁:开锁 上锁
    public interface Lock {
        void lockUp();
        void openlock();
    }
    

    TheftproofDoor.java

    //防盗门:是门(is a),具备所得功能(has a)
    public class TheftproofDoor extends Door implements Lock, DoorBell{
    
        //开门
        public void open() {
            System.out.println("用力推,门打开了");
        }
    
        //关门
        public void close() {
            System.out.println("轻轻拉门,门关上了");
        }
    
        //上锁
        public void lockUp() {
            System.out.println("插进钥匙,向左转3圈,锁上了,拔出钥匙");
        }
    
        //开锁
        public void openlock() {
            System.out.println("插进钥匙,向右转3圈,锁开了,拔出钥匙");
        }
    
        //按门铃拍照存储
        public void takePictures() {
            System.out.println("铃铃铃...咔嚓......拍照存储");
        }
    }
    

    Test.java

    //测试防盗门功能
    public class Test {
        public static void main(String[] args) {
            TheftproofDoor door = new TheftproofDoor();
            //关门上锁
            door.close();
            door.lockUp();
            //有客人拜访
            door.takePictures();
            //开锁开开门
            door.openlock();
            door.open();
        }
    }
    

    3.2 抽象类 VS 接口



    Phone.java

    //抽象类:手机类
    public abstract class Phone {
        private String  brand; //品牌
        private String type; //型号
    
        public Phone(){};
    
        public Phone(String brand, String type) {
            this.brand = brand;
            this.type = type;
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        //输出手机信息
        public void showInfo() {
            System.out.println("这是一台"+brand+type+"手机。");
        }
        //打电话
        public abstract void call();
    
        //发信息
        public abstract void sendMsg();
    }
    

    NetWork.java:

    //接口:上网能力
    public interface NetWork {
        void networkConn();
    }
    

    PlaySth.java

    //接口:播放能力
    public interface PlaySth {
        void play(String content);
    }
    

    TakePhone.java

    //接口:拍照能力
    public interface TakePhone {
        void takePhotos();
    }
    

    CommonPhone.java

    //原始的普通手机,是手机, 只具备播放能力
    public class CommonPhone extends Phone implements PlaySth {
        public CommonPhone(){}
        public CommonPhone(String brand, String type) {
            super(brand, type);
        }
    
        //打电话
        public void call() {
            System.out.println("正在语言通话中......");
        }
    
        //发信息
        public void sendMsg() {
            System.out.println("正在发送文字信息......");
        }
    
        //只能播放音频
        public void play(String content) {
            System.out.println("正在播放音频《"+content+"》......");
        }
    }
    

    SmartPhone.java

    //智能手机:是手机, 且具备上网、拍照、播放能力
    public class SmartPhone extends Phone implements NetWork, TakePhone, PlaySth{
        public SmartPhone(){}
        public SmartPhone(String brand, String type) {
            super(brand, type);
        }
    
        //上网
        public void networkConn() {
            System.out.println("连接上了WIFI网络.......");
        }
    
        //打电话
        public void call() {
            System.out.println("正在视频通话中.....");
        }
    
        //发信息
        public void sendMsg() {
            System.out.println("正在发送文字+图片+音频的信息......");
        }
    
        public void play(String content) {
            System.out.println("正在播放视频《"+content+"》......");
        }
    
        //拍照
        public void takePhotos() {
            System.out.println("卡擦,拍了一张美图......");
        }
    }
    

    Test.java

    //测试类:
    public class Test {
        public static void main(String[] args) {
            CommonPhone phone1 = new CommonPhone("诺基亚", "T5");
            phone1.sendMsg();
            phone1.call();
            phone1.play("慢慢喜欢你");
    
            System.out.println("*********************************");
            SmartPhone phone2 = new SmartPhone("Iphone", "XS Max");
            phone2.sendMsg();
            phone2.play("哪吒");
            phone2.takePhotos();
        }
    }
    

    3.3 接口小结

    接口的作用

    1. 提高程序的可维护性和可扩展性
    2. 提高程序的规范性
    3. 提高程序的安全类

    案例3:打印机

    InkBox.java
    //接口:代表了生产墨盒的标准或约定,可以认为是墨盒的行业生产标准
    public interface InkBox {
        //得到墨盒的颜色
        String getColor();
    }
    

    Paper.java

    //接口:代表了生产纸张的标准或约定,可以认为是纸张的行业生产标准
    public interface Paper {
        //得到纸张大小
        String getSize();
    }
    

    ColorInkBox.java

    //彩色墨盒
    public class ColorInkBox implements InkBox{
    
        //墨盒颜色
        public String getColor() {
            return "彩色";
        }
    }
    

    WhiteBlackInkBox.java

    public class WhiteBlackInkBox implements InkBox{
    
    
        //墨盒颜色
        public String getColor() {
            return "黑白";
        }
    }
    

    A4Paper.java

    //生产A4纸张
    public class A4Paper implements Paper {
    
        public String getSize() {
            return "A4";
        }
    }
    

    B5Paper.java

    public class B5Paper implements Paper{
    
        public String getSize() {
            return "B4";
        }
    }
    

    Printer.java

    //打印机类
    public class Printer {
        //墨盒 纸张  作为成员变量出现
        InkBox inkbox;
        Paper paper;
    
        //安装墨盒
        public void setInkbox(InkBox inkbox) {
            this.inkbox = inkbox;
        }
    
        //往打印机中放纸
        public void setPaper(Paper paper) {
            this.paper = paper;
        }
    
        //使用墨盒在纸张上打印
        public void print() {
            System.out.println("使用"+inkbox.getColor()+"的墨盒,在"+paper.getSize()+"的纸上打印");
        }
    }
    

    Test.java

    //测试类
    public class Test {
        public static void main(String[] args) {
            //买一台打印机
            Printer printer = new Printer();
            InkBox inkbox = null;
            Paper paper = null;
            //彩色打印A4纸
            inkbox = new ColorInkBox();
            paper = new A4Paper();
            printer.setInkbox(inkbox);
            printer.setPaper(paper);
            printer.print();
    
            //黑白打印B5纸
            inkbox = new WhiteBlackInkBox();
            paper = new B5Paper();
            printer.setInkbox(inkbox);
            printer.setPaper(paper);
            printer.print();
        }
    }
    

    案例4:组装电脑



    CPU.java

    public interface CPU {
        String getBrand();
        String getFrequency();
    }
    

    EMS.java

    public interface EMS {
        String getType();
        String getStroage();
    }
    

    HardDisk.java

    public interface HardDisk {
        String getStorage();
    }
    

    IntelCPU.java

    public class IntelCPU implements CPU {
        @Override
        public String getBrand() {
            return "Intel";
        }
    
        @Override
        public String getFrequency() {
            return "3.8GHz";
        }
    }
    

    RAM.java

    public class RAM implements EMS{
        @Override
        public String getType() {
            return "DDR4";
        }
    
        @Override
        public String getStroage() {
            return "4GB";
        }
    }
    

    HDD.java

    public class HDD implements HardDisk{
    
        @Override
        public String getStorage() {
            return "3000GB";
        }
    }
    

    Computer.java

    public class Computer {
        //CPU EMS HardDisk 作为成员变量出现
        CPU cpu;
        EMS ems;
        HardDisk hardDisk;
    
        //组装电脑
        public void setCPU(CPU cpu) {
            this.cpu = cpu;
        }
    
        public void setEMS(EMS ems) {
            this.ems = ems;
        }
    
        public void setHardDisk(HardDisk hardDisk) {
            this.hardDisk = hardDisk;
        }
    
        //打印信息
        public void showInfo() {
            System.out.println("CPU的品牌是:"+cpu.getBrand()+",主频是:"+cpu.getFrequency());
            System.out.println("硬盘容量是:"+hardDisk.getStorage());
            System.out.println("内存类型是:"+ems.getStroage()+",内存容量是:4GB");
        }
    }
    

    Test.java

    public class Test {
        public static void main(String[] args) {
            //购买电脑
            Computer computer = new Computer();
            CPU cpu;
            EMS ems;
            HardDisk hardDisk;
    
            //组装
            cpu = new IntelCPU();
            ems = new RAM();
            hardDisk = new HDD();
    
            computer.setCPU(cpu);
            computer.setEMS(ems);
            computer.setHardDisk(hardDisk);
    
            //显示信息
            computer.showInfo();
        }
    }
    

    相关文章

      网友评论

          本文标题:【JAVA学习笔记】抽象类与接口

          本文链接:https://www.haomeiwen.com/subject/dzoclltx.html