学习自华为开发者学院陈璇老师的JAVA系列课程
一、抽象类
- 没有抽象构造方法,也没有抽象静态方法
- 抽象类中可以有非抽象的构造方法,创造子类的实例时可能调用
例如:
Base.java
//父类
public abstract class Base {
public Base(){
System.out.println("父类(抽象类)的构造方法");
}
}
Son.java
//子类
public class Son extends Base{
public Son() {
System.out.println("子类的构造方法");
}
public static void main(String[] args) {
Son son = new Son();
Base son1 = new Son();
}
}
输出
父类(抽象类)的构造方法
子类的构造方法
父类(抽象类)的构造方法
子类的构造方法
二、接口
2.1 JDK8之前的接口:
接口只允许有抽象的方法
JDK8之前的接口特性:
总结
MyInterface1.java
public interface MyInterface1{
//接口不能有构造方法,也不能被实例化
//静态常量: 接口中的变量,必须是public static final, 且要显示得初始化
//public static final double PI = 3.14;
//等同于
double PI = 3.14;
//JDK8之前,接口中只能有public abstract的方法
public abstract void m1();
//等同于这样声明 public abstract int m2()
int m2();
}
MyInterface2.java
public interface MyInterface2 {
public abstract void m3();
}
Sub1.java
//实现类必须实现接口中的全部抽象方法,除非实现类也是一个抽象类
public class Sub1 implements MyInterface1, MyInterface2 {
public void m1() {
System.out.println("实现类实现了接口中的m1方法");
}
public int m2() {
return 0;
}
public void m3() {
System.out.println("实现类实现了第二个父接口中的m3方法");
}
}
Test.java
public class Test {
public static void main(String[] args) {
//接口可以当做类型来使用
System.out.println(MyInterface1.PI);
MyInterface1 m = new Sub1();
m.m1();
MyInterface2 m2 = new Sub1();
}
}
2.1 JDK8新增的接口特性:
应用场景:
Father.java:
package cn.com.myinterface.pac2;
public abstract class Father {
public void m5() {
System.out.println("抽象类Father中的m5方法");
}
}
MyInterface1.java
package cn.com.myinterface.pac2;
public interface MyInterface1 {
//接口不能有构造方法,也不能被实例化
//静态常量: 接口中的变量,必须是public static final, 且要显示得初始化
//public static final double PI = 3.14;
//等同于
double PI = 3.14;
//JDK8之前,接口中只能有public abstract的方法
public abstract void m1();
//等同于这样声明 public abstract int m2()
int m2();
//JDK8之后,接口中可以定义default默认方法了
default void m3() {
System.out.println("接口MyInterface1中的默认方法m3");
}
default void m5() {
System.out.println("接口MyInterface1中的默认方法m5");
}
//JDK8之后,接口中可以定义static静态方法
static void m6() {
//等同于public static void m6()
System.out.println("接口MyInterface1中的静态方法m6");
}
static void m7() {
//等同于public static void m7()
System.out.println("接口MyInterface1中的静态方法m7");
}
}
MyInterface2.java
package cn.com.myinterface.pac2;
public interface MyInterface2 {
default void m3() {
System.out.println("接口MyInterface2中的默认方法m3");
};
}
Sub1.java
package cn.com.myinterface.pac2;
//实现类必须实现接口中的全部抽象方法,除非实现类也是一个抽象类
public class Sub1 extends Father implements MyInterface1, MyInterface2{
public void m1() {
System.out.println("实现类实现了接口中的m1方法");
}
public int m2() {
return 0;
}
/*当实现类的两个父接口中有同样的默认方法时:
* 解决方案2:子类重写覆盖掉父接口的默认方法m3*/
//public void m3() {
// System.out.println("sub类重写覆盖掉父接口的默认方法m3");
// }
/*当实现类的两个父接口中有同样的默认方法时:
* 解决方案1:子类通过super指定调用哪个父接口的默认方法*/
public void m3() {
MyInterface1.super.m3();
}
}
Test.java
package cn.com.myinterface.pac2;
public class Test {
public static void main(String[] args) {
//接口可以当做类型来使用
//默认方法可以被继承,通过实例调用
System.out.println(MyInterface1.PI);
MyInterface1 m = new Sub1();
m.m3();
MyInterface2 m2 = new Sub1();
m2.m3();
Sub1 s = new Sub1();
s.m3();
//采用类优先的方法,优先继承抽象类中m5方法
m.m5();
s.m5();
//静态方法可以被接口直接调用
MyInterface1.m6();
}
}
三、面向接口编程
程序设计时:
- 关心实现类有何能力,而不关心实现细节
- 面向接口的约定,而不考虑接口的具体实现
案例1
USB.java
//USB接口:描述连接计算机和外部设备的串口总线标准,定义一种输入输出接口的技术规范
public interface USB {
//USB接口并不实现具体功能,通过抽象方法来定义一种数据输入输出规范和标准,能力
void service();
}
USBdisk.java
//满足USB标准的U盘
public class USBdisk implements USB{
public void service() {
System.out.println("连接USB口,开始传输数据");
}
}
USBfan.java
//满足USB标准的风扇
public class USBfan implements USB{
public void service() {
System.out.println("连接USB口,获得电流,风扇开始转动");
}
}
Test.java
//使用接口
public class Test {
public static void main(String[] args) {
//USB风扇
USB uFan = new USBfan();
uFan.service();
//USB标准U盘
USB uDisk = new USBdisk();
uDisk.service();
}
}
总结
image.png
3.1 面向接口编程的步骤
step01.分析类和接口
step02.画类图
进行类的设计
step04.转换为代码
Door.java
//门:抽象方法 开门 关门
public abstract class Door {
public abstract void open();
public abstract void close();
}
DoorBell.java
//门铃:拍照存储
public interface DoorBell {
void takePictures();
}
Lock.java
//锁:开锁 上锁
public interface Lock {
void lockUp();
void openlock();
}
TheftproofDoor.java
//防盗门:是门(is a),具备所得功能(has a)
public class TheftproofDoor extends Door implements Lock, DoorBell{
//开门
public void open() {
System.out.println("用力推,门打开了");
}
//关门
public void close() {
System.out.println("轻轻拉门,门关上了");
}
//上锁
public void lockUp() {
System.out.println("插进钥匙,向左转3圈,锁上了,拔出钥匙");
}
//开锁
public void openlock() {
System.out.println("插进钥匙,向右转3圈,锁开了,拔出钥匙");
}
//按门铃拍照存储
public void takePictures() {
System.out.println("铃铃铃...咔嚓......拍照存储");
}
}
Test.java
//测试防盗门功能
public class Test {
public static void main(String[] args) {
TheftproofDoor door = new TheftproofDoor();
//关门上锁
door.close();
door.lockUp();
//有客人拜访
door.takePictures();
//开锁开开门
door.openlock();
door.open();
}
}
3.2 抽象类 VS 接口
Phone.java
//抽象类:手机类
public abstract class Phone {
private String brand; //品牌
private String type; //型号
public Phone(){};
public Phone(String brand, String type) {
this.brand = brand;
this.type = type;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
//输出手机信息
public void showInfo() {
System.out.println("这是一台"+brand+type+"手机。");
}
//打电话
public abstract void call();
//发信息
public abstract void sendMsg();
}
NetWork.java:
//接口:上网能力
public interface NetWork {
void networkConn();
}
PlaySth.java
//接口:播放能力
public interface PlaySth {
void play(String content);
}
TakePhone.java
//接口:拍照能力
public interface TakePhone {
void takePhotos();
}
CommonPhone.java
//原始的普通手机,是手机, 只具备播放能力
public class CommonPhone extends Phone implements PlaySth {
public CommonPhone(){}
public CommonPhone(String brand, String type) {
super(brand, type);
}
//打电话
public void call() {
System.out.println("正在语言通话中......");
}
//发信息
public void sendMsg() {
System.out.println("正在发送文字信息......");
}
//只能播放音频
public void play(String content) {
System.out.println("正在播放音频《"+content+"》......");
}
}
SmartPhone.java
//智能手机:是手机, 且具备上网、拍照、播放能力
public class SmartPhone extends Phone implements NetWork, TakePhone, PlaySth{
public SmartPhone(){}
public SmartPhone(String brand, String type) {
super(brand, type);
}
//上网
public void networkConn() {
System.out.println("连接上了WIFI网络.......");
}
//打电话
public void call() {
System.out.println("正在视频通话中.....");
}
//发信息
public void sendMsg() {
System.out.println("正在发送文字+图片+音频的信息......");
}
public void play(String content) {
System.out.println("正在播放视频《"+content+"》......");
}
//拍照
public void takePhotos() {
System.out.println("卡擦,拍了一张美图......");
}
}
Test.java
//测试类:
public class Test {
public static void main(String[] args) {
CommonPhone phone1 = new CommonPhone("诺基亚", "T5");
phone1.sendMsg();
phone1.call();
phone1.play("慢慢喜欢你");
System.out.println("*********************************");
SmartPhone phone2 = new SmartPhone("Iphone", "XS Max");
phone2.sendMsg();
phone2.play("哪吒");
phone2.takePhotos();
}
}
3.3 接口小结
接口的作用
- 提高程序的可维护性和可扩展性
- 提高程序的规范性
- 提高程序的安全类
案例3:打印机
InkBox.java
//接口:代表了生产墨盒的标准或约定,可以认为是墨盒的行业生产标准
public interface InkBox {
//得到墨盒的颜色
String getColor();
}
Paper.java
//接口:代表了生产纸张的标准或约定,可以认为是纸张的行业生产标准
public interface Paper {
//得到纸张大小
String getSize();
}
ColorInkBox.java
//彩色墨盒
public class ColorInkBox implements InkBox{
//墨盒颜色
public String getColor() {
return "彩色";
}
}
WhiteBlackInkBox.java
public class WhiteBlackInkBox implements InkBox{
//墨盒颜色
public String getColor() {
return "黑白";
}
}
A4Paper.java
//生产A4纸张
public class A4Paper implements Paper {
public String getSize() {
return "A4";
}
}
B5Paper.java
public class B5Paper implements Paper{
public String getSize() {
return "B4";
}
}
Printer.java
//打印机类
public class Printer {
//墨盒 纸张 作为成员变量出现
InkBox inkbox;
Paper paper;
//安装墨盒
public void setInkbox(InkBox inkbox) {
this.inkbox = inkbox;
}
//往打印机中放纸
public void setPaper(Paper paper) {
this.paper = paper;
}
//使用墨盒在纸张上打印
public void print() {
System.out.println("使用"+inkbox.getColor()+"的墨盒,在"+paper.getSize()+"的纸上打印");
}
}
Test.java
//测试类
public class Test {
public static void main(String[] args) {
//买一台打印机
Printer printer = new Printer();
InkBox inkbox = null;
Paper paper = null;
//彩色打印A4纸
inkbox = new ColorInkBox();
paper = new A4Paper();
printer.setInkbox(inkbox);
printer.setPaper(paper);
printer.print();
//黑白打印B5纸
inkbox = new WhiteBlackInkBox();
paper = new B5Paper();
printer.setInkbox(inkbox);
printer.setPaper(paper);
printer.print();
}
}
案例4:组装电脑
CPU.java
public interface CPU {
String getBrand();
String getFrequency();
}
EMS.java
public interface EMS {
String getType();
String getStroage();
}
HardDisk.java
public interface HardDisk {
String getStorage();
}
IntelCPU.java
public class IntelCPU implements CPU {
@Override
public String getBrand() {
return "Intel";
}
@Override
public String getFrequency() {
return "3.8GHz";
}
}
RAM.java
public class RAM implements EMS{
@Override
public String getType() {
return "DDR4";
}
@Override
public String getStroage() {
return "4GB";
}
}
HDD.java
public class HDD implements HardDisk{
@Override
public String getStorage() {
return "3000GB";
}
}
Computer.java
public class Computer {
//CPU EMS HardDisk 作为成员变量出现
CPU cpu;
EMS ems;
HardDisk hardDisk;
//组装电脑
public void setCPU(CPU cpu) {
this.cpu = cpu;
}
public void setEMS(EMS ems) {
this.ems = ems;
}
public void setHardDisk(HardDisk hardDisk) {
this.hardDisk = hardDisk;
}
//打印信息
public void showInfo() {
System.out.println("CPU的品牌是:"+cpu.getBrand()+",主频是:"+cpu.getFrequency());
System.out.println("硬盘容量是:"+hardDisk.getStorage());
System.out.println("内存类型是:"+ems.getStroage()+",内存容量是:4GB");
}
}
Test.java
public class Test {
public static void main(String[] args) {
//购买电脑
Computer computer = new Computer();
CPU cpu;
EMS ems;
HardDisk hardDisk;
//组装
cpu = new IntelCPU();
ems = new RAM();
hardDisk = new HDD();
computer.setCPU(cpu);
computer.setEMS(ems);
computer.setHardDisk(hardDisk);
//显示信息
computer.showInfo();
}
}
网友评论