day13 抽象类和接口

抽象类和接口

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.什么场景使用哪个?

当你关注事物的本质,使用抽象类

当你关注某个功能,使用接口

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于抽象类接口Java作业题目,主要考察学生对于Java基础知识的掌握程度和编程能力。以下是一个可能的实现方法: 首先,需要定义一个接口 `LeapYearChecker`,包含一个方法 `isLeapYear(int year)`,用于判断给定的年份是否为闰年。接口定义如下: ```java public interface LeapYearChecker { boolean isLeapYear(int year); } ``` 接着,定义一个抽象类 `AbstractLeapYearChecker`,实现 `LeapYearChecker` 接口中的 `isLeapYear` 方法,并提供一个 `check` 方法,用于在控制台中输出判断结果。抽象类定义如下: ```java import java.util.Calendar; public abstract class AbstractLeapYearChecker implements LeapYearChecker { @Override public boolean isLeapYear(int year) { Calendar calendar = Calendar.getInstance(); calendar.clear(); calendar.set(Calendar.YEAR, year); return calendar.getActualMaximum(Calendar.DAY_OF_YEAR) > 365; } public void check(int year) { System.out.printf("%d is%s a leap year.\n", year, isLeapYear(year) ? "" : " not"); } } ``` 最后,定义一个 `Main` 类,用于读取用户输入的年份,并调用 `AbstractLeapYearChecker.check` 方法进行判断。`Main` 类定义如下: ```java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Please input a year: "); int year = scanner.nextInt(); scanner.close(); AbstractLeapYearChecker checker = new AbstractLeapYearChecker() {}; checker.check(year); } } ``` 这样,用户输入一个年份后,程序会输出该年份是否为闰年。可以通过继承 `AbstractLeapYearChecker` 类,自定义实现 `isLeapYear` 方法来实现其他判断闰年的算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值