美文网首页Java 杂谈
Java入门系列-18-抽象类和接口

Java入门系列-18-抽象类和接口

作者: 要成为王的男人 | 来源:发表于2018-10-22 17:20 被阅读0次

    抽象类

    在第16节继承中,有父类 People

    People people=new People();
    people.sayHi();
    

    实例化People是没有意义的,因为“人”是一个抽象的概念。

    怎么才能避免父类的实例化呢?使用 abstract 关键字修饰类(抽象类)。

    抽象父类

    public abstract class People {
        private String name;
        
        public People(String name) {
            super();
            this.name = name;
        }
    
        //人类共有方法 哭
        public void cry() {
            System.out.println("呜呜");
        }
        //抽象方法 不做具体实现
        public abstract void sayHi();
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    子类:Chinese.java

    //中国人
    public class Chinese extends People{
    
        public Chinese(String name) {
            super(name);
        }
    
        //必须实现
        @Override
        public void sayHi() {
            System.out.println(this.getName()+":你好!");
        }
    }
    

    子类:Britisher.java

    //英国人
    public class Britisher extends People{
    
        public Britisher(String name) {
            super(name);
        }
    
        @Override
        public void sayHi() {
            System.out.println(this.getName()+":Hello!");
        }
    }
    

    测试类

    public class TestPeople {
    
        public static void main(String[] args) {
            //People people=new People("张三");//去掉注释试试
            People chinese=new Chinese("张三");
            chinese.sayHi();
            People britisher=new Britisher("John");
            britisher.sayHi();
        }
    }
    

    被关键字 abstract 修饰的类是抽象类,抽象类不能实例化

    被关键字 abstract 修饰的方法是抽象方法,抽象方法没有方法体

    抽象方法必须在抽象类里

    抽象方法必须在子类中被实现,除非子类是抽象类

    抽象方法没有方法体
    public abstract void sayHi();

    注意:被 abstract 修饰后不能使用 final 修饰!

    接口

    如何实现防盗门这个类?门有“开”和“关”的功能,锁有“上锁”和“开锁”的功能,将门和锁分别定义为抽象类。但是防盗门可以继承门的同时又继承锁吗?不能,防盗门不是锁,不符合 is a 的关系而且Java只支持单继承。

    接口的语法

    public interface MyInterface {
        public abstract void foo();
    }
    

    接口可以认为是纯粹的抽象类

    接口中的方法都是抽象方法 (public abstract)

    接口不可以被实例化

    实现类必须实现接口中的所有方法

    接口中的变量都是静态常量

    接口之间可以互相继承(extedns),类只能实现接口(implements)

    一个类可以继承一个父类,实现多个接口

    演示接口的继承及实现接口

    父接口:A.java

    public interface A {
        void methodA();
    }
    

    子接口:B.java

    public interface B extends A{
        void methodB();
    }
    

    接口的实现类:C.java

    public class C implements B{
    
        @Override
        public void methodA() {
        }
    
        @Override
        public void methodB() {
        }
    }
    

    接口表示能力

    面向接口编程时,关心实现类有何能力,而不关心实现细节。面向接口的约定而不考虑接口的具体实现。

    在鸟类中,白鹭可以飞,鸵鸟不能飞,所以在这里飞是一种能力,下面看一下代码的设计。

    飞行接口:Fly.java

    //表示飞行能力
    public interface Fly {
        /**
         * 飞行
         */
        public abstract void fly();
    }
    

    游泳接口:Swim.java

    //表示游泳能力
    public interface Swim {
        public abstract void swim();
    }
    

    鸟类:Bird.java

    //抽象鸟类 重用代码
    public abstract class Bird {
        /**
         * 下蛋
         */
        public void layEggs() {
            System.out.println("产出一枚蛋");
        }
    }
    

    白鹭类:Egret.java

    //白鹭类
    public class Egret extends Bird implements Fly,Swim{
    
        @Override
        public void fly() {
            System.out.println("使劲煽动翅膀后起飞");
        }
    
        @Override
        public void swim() {
            System.out.println("漂在了水面上,轻松的游来游去");
        }
    }
    

    鸵鸟类:Ostrich.java

    //鸵鸟类
    public class Ostrich extends Bird implements Swim{
    
        @Override
        public void swim() {
            System.out.println("漂在了水面了,开始游动");
        }
    }
    

    测试类

    public class TestBird {
        public static void main(String[] args) {
            Egret egret=new Egret();
            egret.swim();
            egret.fly();
            Ostrich ostrich=new Ostrich();
            ostrich.swim();
        }
    }
    

    接口表示约定

    在生活中,我们使用的插座,规定了两个接头剪得额定电压、两个接头间的距离、接头的形状。

    在代码中约定体现在接口名称和注释上

    下面使用面向接口编程实现一台计算机的组装,计算机的组成部分有:CPU、硬盘、内存。

    先创建 CPU、硬盘、内存接口

    package computer;
    
    /**
     * CPU 接口
     * @author Jack
     *
     */
    public interface CPU {
        /**
         * 获取CPU品牌
         * @return
         */
        String getBrand();
        
        /**
         * 获取CPU主频
         * @return
         */
        Float getFrequency();
    }
    
    package computer;
    
    /**
     * 硬盘接口
     * @author Jack
     *
     */
    public interface HardDisk {
        
        /**
         * 获取硬盘容量
         * @return
         */
        int getCapacity();
    }
    
    package computer;
    
    /**
     * 内存接口
     * @author Jack
     *
     */
    public interface EMS {
        /**
         * 获取内存容量
         * @return
         */
        int getSize();
    }
    

    将接口设计到计算机类中

    package computer;
    /**
     * 计算机类
     * @author Jack
     *
     */
    public class Computer {
        private CPU cpu;//cpu接口
        private HardDisk hardDisk;//硬盘接口
        private EMS ems;//内存接口
    
        public Computer() {
        }
    
        public Computer(CPU cpu, HardDisk hardDisk, EMS ems) {
            super();
            this.cpu = cpu;
            this.hardDisk = hardDisk;
            this.ems = ems;
        }
    
        public CPU getCpu() {
            return cpu;
        }
    
        public void setCpu(CPU cpu) {
            this.cpu = cpu;
        }
    
        public HardDisk getHardDisk() {
            return hardDisk;
        }
    
        public void setHardDisk(HardDisk hardDisk) {
            this.hardDisk = hardDisk;
        }
    
        public EMS getEms() {
            return ems;
        }
    
        public void setEms(EMS ems) {
            this.ems = ems;
        }
    }
    

    创建 CPU、硬盘、内存接口的实现

    package computer.impl;
    
    import computer.CPU;
    
    /**
     * 英特尔 CPU
     * @author Jack
     *
     */
    public class IntelCPU implements CPU{
    
        @Override
        public String getBrand() {
            return "英特尔";
        }
    
        @Override
        public Float getFrequency() {
            return 2.3f;
        }
    }
    
    package computer.impl;
    
    import computer.HardDisk;
    
    /**
     * 闪迪硬盘
     * @author Jack
     *
     */
    public class SanDisk implements HardDisk{
    
        @Override
        public int getCapacity() {
            return 3000;
        }
    }
    
    package computer.impl;
    
    import computer.EMS;
    
    /**
     * 金士顿 内存
     * @author Jack
     *
     */
    public class JSDEMS implements EMS{
    
        @Override
        public int getSize() {
            return 4;
        }
    }
    

    完成计算机及组件的组装进行测试

    package computer;
    
    import computer.impl.IntelCPU;
    import computer.impl.JSDEMS;
    import computer.impl.SanDisk;
    
    public class TestComputer {
        public static void main(String[] args) {
            CPU cpu=new IntelCPU();//创建CPU
            HardDisk sanDisk=new SanDisk();//创建硬盘
            EMS jsdEMS=new JSDEMS();//创建内存
            Computer computer=new Computer(cpu,sanDisk,jsdEMS);
            System.out.println("CPU型号:"+computer.getCpu().getBrand());
            System.out.println("硬盘容量:"+computer.getHardDisk().getCapacity()+" GB");
            System.out.println("内存容量:"+computer.getEms().getSize()+" GB");
        }
    }
    

    接口总结

    接口有比抽象类更好的特性:
    1.可以被多继承
    2.设计和实现完全分离
    3.更自然的使用多态
    4.更容易搭建程序框架
    5.更容易更换实现

    搜索关注公众号「享智同行」,第一时间获取技术干货

    相关文章

      网友评论

        本文标题:Java入门系列-18-抽象类和接口

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