Java入門系列-18-抽象類和接口

抽象類

在第16節繼承中,有父類 Peoplejava

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

實例化People是沒有意義的,由於「人」是一個抽象的概念。編程

怎麼才能避免父類的實例化呢?使用 abstract 關鍵字修飾類(抽象類)。框架

抽象父類ide

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.javathis

//英國人
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 修飾的類是抽象類,抽象類不能實例化code

被關鍵字 abstract 修飾的方法是抽象方法,抽象方法沒有方法體繼承

抽象方法必須在抽象類裏dns

抽象方法必須在子類中被實現,除非子類是抽象類

抽象方法沒有方法體
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.更容易更換實現

搜索關注公衆號「享智同行」,第一時間獲取技術乾貨

相關文章
相關標籤/搜索