Java入門系列-18-抽象類和介面
抽象類
在第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.更容易更換實現
搜尋關注公眾號「享智同行」,第一時間獲取技術乾貨