抽象类
在第 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. 更容易更换实现
来源: https://www.cnblogs.com/AIThink/p/9831291.html