为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Java

抽象类

在第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");
    }
}



作者:极客大全
链接:https://www.jianshu.com/p/287f535298e5


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消