抽象类和接口
1. 抽象类描述
1.抽象方法没有方法体 必须存在于抽象类中 均使用abstract关键字修饰
2.抽象类不能直接new对象,必须通过new子类的方式创建对象(多态向上转型)
3.子类必须重写抽象类中的所有抽象方法 除非子类也是抽象类
4.抽象类中可以书写普通属性,普通方法,静态方法,构造方法
5.抽象类实现多态的方式与之前一致 父类作为形参/父类作为返回值/父类类型数组&集合
2. 抽象类案例
package com.atguigu.test2;
/**
* 门:父类
* */
public abstract class Door {
private String brand; // 品牌
private double price; // 价格
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Door() {
}
public Door(String brand, double price) {
this.brand = brand;
this.price = price;
}
public abstract void open(); // 开门
public abstract void close(); // 关门
}
package com.atguigu.test2;
/**
* 普通门 继承了父类Door 需要实现所有抽象方法
* */
public class CommonDoor extends Door{
@Override
public void open() {
System.out.println("普通门开门");
}
@Override
public void close() {
System.out.println("普通门关门");
}
}
package com.atguigu.test2;
/**
* 防盗门 继承父类 Door 需要实现所有抽象方法
* */
public class SecurityDoor extends Door{
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public SecurityDoor() {
}
public SecurityDoor(String brand, double price, String password) {
super(brand, price);
this.password = password;
}
@Override
public void open() {
System.out.println("防盗门开门");
}
@Override
public void close() {
System.out.println("防盗门关门");
}
}
package com.atguigu.test2;
/**
* 人类
* 提供用于操作门 的方法
* */
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 开普通门
public void openCommonDoor(CommonDoor cd){
cd.open();
}
// 关普通门
public void closeCommonDoor(CommonDoor cd){
cd.close();
}
// 开防盗门
public void openSecurityDoor(SecurityDoor sd){
sd.open();
}
// 关防盗门
public void closeSecurityDoor(SecurityDoor sd){
sd.close();
}
// 开门 形参使用父类,实参使用子类
public void openDoor(Door door){
door.open();
}
// 关门 形参使用父类,实参使用子类
public void closeDoor(Door door){
door.close();
}
public CommonDoor buyCommonDoor(){
CommonDoor cd = new CommonDoor();
cd.setBrand("金刚");
cd.setPrice(500);
return cd;
}
public SecurityDoor buySecurityDoor(){
SecurityDoor sd = new SecurityDoor();
sd.setBrand("大力士");
sd.setPrice(1500);
return sd;
}
public Door buyDoor(double money){
if (money >= 1000){
SecurityDoor sd = new SecurityDoor();
sd.setBrand("大力士");
sd.setPrice(1500);
return sd;
}else {
CommonDoor cd = new CommonDoor();
cd.setBrand("金刚");
cd.setPrice(500);
return cd;
}
}
}
package com.atguigu.test2;
public class TestDoor {
public static void main(String[] args) {
Person zs = new Person();
zs.setName("赵四");
CommonDoor cd = new CommonDoor();
cd.setBrand("小金刚");
cd.setPrice(500);
zs.openCommonDoor(cd); // 普通门开门
zs.closeCommonDoor(cd); // 普通门关门
System.out.println("-----------------");
SecurityDoor sd = new SecurityDoor();
sd.setBrand("大金刚");
sd.setPrice(1500);
zs.openSecurityDoor(sd); // 防盗门开门
zs.closeSecurityDoor(sd); // 防盗门关门
System.out.println("------------------");
zs.openDoor(cd); // 普通门开门
zs.closeDoor(cd); // 普通门关门
zs.openDoor(sd); // 防盗门开门
zs.closeDoor(sd); // 防盗门关门
System.out.println("-------------------");
// 父类类型数组 里面存放子类对象
Door[] doors = new Door[2];
doors[0] = new CommonDoor();
doors[1] = new SecurityDoor();
}
}
3. 接口描述
1.接口中的方法默认都是全局抽象方法 不管是否书写 都使用public abstract修饰
2.接口不能直接new对象 必须通过new实现类(子类)的方式创建对象 (多态向上转型)
3.实现类(子类)必须重写父类中的抽象方法 除非实现类(子类)也是抽象类 或者 是接口
4.接口中不能书写 普通属性(JDK7-) 普通方法(JDK7-) 静态方法(JDK7-) 构造方法
5.接口实现多态的方式与之前一致 父类作为形参 父类作为返回值 父类作为数组/集合 类型
6.一个类只能继承一个父类 但是可以实现多个接口
7.接口可以继承多个接口
面试题:Java支持多继承吗?
不支持,但是可以使用接口继承多个接口的方式 实现类似多继承的效果
JDK8接口新特性
1.可以书写普通方法 在返回值之前加上default关键字
2.可以书写静态方法
4. 接口案例
4.1 接口实现手机
package com.atguigu.test5;
/**
* 手机类 父类
*
* 当前类中将call方法 和 sendMessage方法 定义为抽象方法有如下两个原因:
* 1.因为当前类属于手机类 具体手机类型不明确 行为过程有差异 无法描述
* 2.将这两个方法写为抽象方法 便可以要求子类强制实现 即:只要是手机必须可以发短信 打电话
* */
public abstract class Phone {
private String type;
private String brand;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public abstract void call();
public abstract void sendMessage(String message);
}
package com.atguigu.test5;
/**
* 如果某个类 即要继承父类 又要实现接口
* 必须先继承 后实现
* */
public class CommonPhone extends Phone implements Game, NetWork, Audio{
private String keyType; // 键盘类型
public String getKeyType() {
return keyType;
}
public void setKeyType(String keyType) {
this.keyType = keyType;
}
@Override
public void call() {
System.out.println("普通手机打电话");
}
@Override
public void sendMessage(String message) {
System.out.println("普通手机发短信,按键打字:" + message);
}
@Override
public void playAudio(String audioName) {
System.out.println("普通手机播放音乐,音质感人:" + audioName);
}
@Override
public void playGame(String game) {
System.out.println("普通手机打游戏:" + game);
}
@Override
public void connect() {
System.out.println("普通手机连接网络,卡的飞起");
}
}
package com.atguigu.test5;
public class SmartPhone extends Phone implements Game, NetWork, Audio, Video, Photo{
private String screenSize; // 屏幕尺寸
public String getScreenSize() {
return screenSize;
}
public void setScreenSize(String screenSize) {
this.screenSize = screenSize;
}
@Override
public void playAudio(String audioName) {
System.out.println("智能手机播放音乐,音质完美:" + audioName);
}
@Override
public void playGame(String game) {
System.out.println("智能手机打游戏,操作流程:" + game);
}
@Override
public void connect() {
System.out.println("智能手机连接网络,十分流畅");
}
@Override
public void call() {
System.out.println("智能手机打电话,语言拨号");
}
@Override
public void sendMessage(String message) {
System.out.println("智能手机发短信,语音输入:" + message);
}
@Override
public void takePhoto() {
System.out.println("智能手机拍照,记录生活");
}
@Override
public void playVideo(String videoName) {
System.out.println("智能手机播放视频:" + videoName);
}
}
package com.atguigu.test5;
/**
* 音频接口
* */
public interface Audio {
void playAudio(String audioName);
}
package com.atguigu.test5;
/**
* 游戏接口
* */
public interface Game {
void playGame(String game);
}
package com.atguigu.test5;
/**
* 网络接口
* */
public interface NetWork {
void connect();
}
package com.atguigu.test5;
/**
* 拍照接口
* */
public interface Photo {
void takePhoto();
}
package com.atguigu.test5;
/**
* 视频接口
* */
public interface Video {
void playVideo(String videoName);
}
package com.atguigu.test5;
public class Test {
public static void main(String[] args) {
CommonPhone nokia = new CommonPhone();
nokia.setBrand("诺基亚");
nokia.setKeyType("九键");
nokia.setKeyType("N95");
nokia.sendMessage("在吗"); // 普通手机发短信,按键打字:在吗
nokia.call(); // 普通手机打电话
nokia.playGame("贪吃蛇"); // 普通手机打游戏:贪吃蛇
nokia.playAudio("追梦赤子心"); // 普通手机播放音乐,音质感人:追梦赤子心
nokia.connect(); // 普通手机连接网络,卡的飞起
System.out.println("-------------------");
SmartPhone huawei = new SmartPhone();
huawei.setBrand("华为");
huawei.setType("Mate 50 PRO MAX PLUS");
huawei.setScreenSize("18");
huawei.sendMessage("还在吗"); // 智能手机发短信,语音输入:还在吗
huawei.call(); // 智能手机打电话,语言拨号
huawei.playAudio("不用去猜"); // 智能手机播放音乐,音质完美:不用去猜
huawei.playGame("王者荣耀"); // 智能手机打游戏,操作流程:王者荣耀
huawei.connect(); // 智能手机连接网络,十分流畅
huawei.takePhoto(); // 智能手机拍照,记录生活
huawei.playVideo("脸对脸背对背"); // 智能手机播放视频:脸对脸背对背
}
}
4.2 接口实现打印机
package com.atguigu.test6;
/**
* 打印机
* 属性:墨盒 和 纸张
* */
public class Printer {
private InkBox inkBox;
private Paper paper;
public InkBox getInkBox() {
return inkBox;
}
public void setInkBox(InkBox inkBox) {
this.inkBox = inkBox;
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public void print(){
System.out.println("使用" + getInkBox().inkBoxColor() + "墨盒" + getPaper().paperSize() + "纸张上打印");
}
}
package com.atguigu.test6;
public interface InkBox {
String inkBoxColor();
}
package com.atguigu.test6;
public class BlackInkBox implements InkBox {
@Override
public String inkBoxColor() {
return "黑色墨盒";
}
}
package com.atguigu.test6;
public class ColorInkBox implements InkBox{
@Override
public String inkBoxColor() {
return "彩色墨盒";
}
}
package com.atguigu.test6;
public interface Paper {
String paperSize();
}
package com.atguigu.test6;
public class A4 implements Paper{
@Override
public String paperSize() {
return "A4";
}
}
package com.atguigu.test6;
public class B5 implements Paper{
@Override
public String paperSize() {
return "B5";
}
}
package com.atguigu.test6;
public class Test {
public static void main(String[] args) {
Printer hp = new Printer();
InkBox blank = new BlackInkBox();
Paper a4 = new A4();
hp.setInkBox(blank);
hp.setPaper(a4);
hp.print(); // 使用黑色墨盒墨盒A4纸张上打印
System.out.println("----------------");
InkBox color = new ColorInkBox();
Paper b5 = new B5();
hp.setInkBox(color);
hp.setPaper(b5);
hp.print(); // 使用彩色墨盒墨盒B5纸张上打印
System.out.println("----------------");
// 接口类型数组 也可以存放子类对象
InkBox[] inks = new InkBox[2];
inks[0] = new BlackInkBox();
inks[1] = new ColorInkBox();
Paper[] ps = new Paper[2];
ps[0] = new A4();
ps[1] = new B5();
}
}
5. 抽象类和接口的区别?
1.接口和抽象类区别?
2.什么场景使用哪个?
当你关注事物的本质,使用抽象类
当你关注某个功能,使用接口