抽象类方法和接口

一、抽象类 方法

1.抽象方法使用规则

  1. 抽象方法没有方法体
  2. 含有抽象方法的类必须是抽象类
  3. 抽象类中可以暂时没有抽象方法
  4. 抽象类中的抽象方法跟子类有什么联系?
    (1) 如果子类完全实现了父类的抽象方法,那么子类可以不用声明为抽象类
    (2) 如果子类没有完全实现父类的抽象方法,那么子类必须声明为抽象类

2.抽象类的语法规则

  1. 被abstract修饰的类是抽象类
  2. 抽象类中可以有抽象方法,也就是被abstract修饰的方法,也可以没有。
  3. 抽象方法没有方法体,只有方法声明。
  4. 子类继承抽象类需要重写父类所有的抽象方法,否则,子类也必须声明为抽象类
  5. 抽象类有构造方法,但是不能被显示调用,也就是不能实例化,或者说抽象类没有对象。–防止直接调用抽象方法
  6. 抽象类的构造方法只在子类实例化时隐式调用。
  7. 抽象类的使用一般是作为引用类型,指向非抽象的引用实例,体现出多态。
  8. 构造方法和静态方法都不能(abstract)抽象修饰
    静态方法不能被子类覆盖(重写),一旦声明为抽象方法 将永远没有具体的实现
public abstract class FoolishMan {
    public abstract void moveMoutain();
    public abstract void fillOcean();
}

public abstract class Zi1 extends FoolishMan{

}
public abstract class Zi2 extends Zi1{
    @Override
    public void moveMoutain() {
        System.out.println("第三代完成了移山");
    }
}
public class Zi3 extends Zi2{
    @Override
    public void fillOcean() {
        System.out.println("完成了填海");
    }
}

public class TestFool {
    public static void main(String[] args) {
        //抽象类有构造方法,但是不能被显示调用,也就是不能实例化,
        // 或者说抽象类没有对象。--防止直接调用抽象方法
        Zi3 z3 = new Zi3();
        z3.fillOcean();
        z3.moveMoutain();
    }
}
完成了填海
第三代完成了移山

二、接口

接口的含义:

接口就是提供一种统一的“协议”,而接口中的属性也属于“协议”中的成员.它们是公共的,静态的,最终的常量.相当于全局常量。

抽象类是不完全的类,相当于是接口和具体类的一个中间层.即满足接口的抽象,也满足具体的实现.

接口的语法规则

  1. 定义一个接口:
    public interface 接口名{}

  2. 接口的成员:
    成员属性:public static final (公共的静态常量)类型
    成员方法:public abstract (公共的抽象方法) 或静态方法
    无实例方法

  3. 接口的应用理解:
    接口可以理解为定义的一组通用的组件,或者是对外提供服务的功能模块,具体可替换,可拆卸的特点接口比抽象类更抽象,已经完全抽象得没边没影。
    接口通常作为实体类的成员属性,和实体类是附属关系,而不是包含关系。

1.为什么接口中的属性是静态的常量?

(1) 首先接口由于少了方法的实现,所以不能实例化,这个与抽象类一致,
(2) 由于不能实例化,所以对于成员变量只能是static
(3) 由于是static所以所有实现了接口的类共享一份
(4) 由于所有人共享一份,同时接口的定义是“所有实现该接口的人都共同拥有这些属性/功能
(5) 由于所有的实现类都共同拥有,若是变量则实现类A的改变会导致实现B的改变
(6) 会由于实现类的操作而改变的东西违反了接口的定义
(7) 所以为了确保每个实现的接口都共同遵守这个“属性”,属性必须是final
(8) 由于接口本身的定义是public,最后就是 public static final xxx

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 show(){
        System.out.println("使用"+inkBox.type()+"墨盒,在"+paper.size()+"纸张上打印");
    }
}
public interface Paper {
    String size();
}
public interface InkBox {
    String type();
}
public class A4 implements Paper {

    @Override
    public String size() {
        return "A4";
    }
}
public class B5 implements Paper {
    @Override
    public String size() {
        return "B5";
    }
}
public class Black implements InkBox {
    @Override
    public String type() {
        return "黑色";
    }
}
public class ColorBox implements InkBox {

    @Override
    public String type() {
        return "彩色";
    }
}
public class Test {
    public static void main(String[] args) {
        Printer p = new Printer();
        p.setInkBox(new ColorBox());//接口的实现类赋值
        p.setPaper(new A4());
        p.show();
    }
}

使用彩色墨盒,在A4纸张上打印

接口实现计算机
需求说明:采用面向接口编程思想组装一台计算机,计算机的主要组成部分有:CPU、硬盘、内存:首先,定义CPU的接口CPU,返回CPU品牌和主频;其次,定义内存的接口EMS,返回容量;再次,定义硬盘的接口HardDisk,返回容量;然后,编写各组件厂商分别实现CPU、EMS、和HardDisk接口,编写计算机类,组装计算机并显示相关信息;最后,编写测试类运行如图所示的效果。

public class Computer {
    //接口作为成员属性进行封装
    private Cpu cpu;
    private EMS ems;
    private  HandDisk handDisk;

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }

    public EMS getEms() {
        return ems;
    }

    public void setEms(EMS ems) {
        this.ems = ems;
    }

    public HandDisk getHandDisk() {
        return handDisk;
    }

    public void setHandDisk(HandDisk handDisk) {
        this.handDisk = handDisk;
    }


    public void show(){
        System.out.println("计算机信息如下:\nCpu的品牌是:"+cpu.brand()+",主频是:"
                +cpu.hz()+"HZ\n"+"硬盘容量是:"+handDisk.size()+"GB\n"+"内存容量是:"+ems.size()+"GB\n");
    }
}
public interface Cpu {
    String brand();
    String hz();
}
public interface EMS {
    int size();
}
public interface HandDisk {
    int  size();
}

public class CpuImpl implements Cpu {
    @Override
    public String brand() {
        return "Inter";
    }

    @Override
    public String hz() {
        return "3.84";
    }
}
public class EmsImpl implements EMS {
    @Override
    public int size() {
        return 4;
    }
}
public class HandDiskImpl implements HandDisk {
    @Override
    public int size() {
        return 3000;
    }
}

public class TestComputer {
    public static void main(String[] args) {
        Computer c = new Computer();
        c.setCpu(new CpuImpl());
        c.setEms(new EmsImpl());
        c.setHandDisk(new HandDiskImpl());
        c.show();
    }
}
计算机信息如下:
Cpu的品牌是:Inter,主频是:3.84HZ
硬盘容量是:3000GB
内存容量是:4GB

关于default

1.Jdk8开始,允许接口中有实例方法,但是必须被default修饰

2.出现背景:
对已有的接口,如果想对接口增加一个新方法,那么需要对实现该接口的所有类进行修改,如果接口实的现类很多,就会带来很大的工作量,而且还很容易破坏以前的代码,带来一些问题。如果把新的方法定义为default方法,就可以避免对其他实现类的修改。

3.语法规则:
1.实现类不需要重写default修饰的方法 但是也会继承接口中的default方法

2.如果一个类同时实现接口A和B,接口A和B中有相同的default方法,这时,该类必须重写接口中的default方法。为什么要重写呢?是因为,类在继承接口中的default方法时,不知道应该继承哪一个接口中的default方法。

3.如果子类继承父类,父类中有b方法,该子类同时实现的接口中也有b方法(被default修饰),那么子类需要同时重写父类和接口中的b方法。

4.如果一个接口A被标记成函数式接口,那么他所继承的父接口中的抽象方法 必须要用default方法重写,因为函数式接口的规定是:接口中只能有一个抽象方法。接口A中的抽象方法加上继承的父接口中的抽象方法个数之和只能是1.

关键字总结
截至目前,我们学过的面向对象中关键字有:this ,super ,abstract ,static 。

需求说明:原始的手机,可以发短信,通电话。随着发展,手机增加了音频、视频播放、拍照、上网功能。按照作业3的思路和下面的类图进行程序设计:首先,编写类及接口,参照以下类的结构图;其次,编写测试类,让普通手机播放音频、发信息和通电话,让智能手机上网、播放视频、照相、发彩信和视频通电话。
抽象类方法和接口_第1张图片

public abstract class Handest {
    //属性
    private String brand;
    private String 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;
    }

    //方法
    abstract void sendInfo();
    abstract void call();
    public void info(String type,String brand){
        System.out.println("这是一款型号为"+type+"的"+brand+"手机");
    }
}
public class AptitudeHandst extends Handest implements Play,Network,TakePicture{
    @Override
    void sendInfo() {
        System.out.println("开始发送带图片与文字信息.......");
    }

    @Override
    void call() {
        System.out.println("开始视频通话.......");
    }

    @Override
    public void play(String radio) {
        System.out.println("开始播放视频《"+radio+"》");
    }

    @Override
    public void newWork() {
        System.out.println("已经启动移动网络");
    }

    @Override
    public void takePicture() {
        System.out.println("咔嚓.....拍照成功");
    }
}
public class CommonHandest extends Handest implements Play {
    @Override
    void sendInfo() {
        System.out.println("开始发送文字信息.......");
    }

    @Override
    void call() {
        System.out.println("开始语音通话.......");
    }

    @Override
    public void play(String music) {
        System.out.println("开始播放音乐《"+music+"》");
    }
}
public interface Play {
    void play(String content);
}

public interface Network {
    void newWork();
}
public interface TakePicture {
    void takePicture();
}

public class TestPhone {
    public static void main(String[] args) {
        CommonHandest c = new CommonHandest();
        c.info("GB121","小辣椒");
        c.play("啦啦啦");
        c.sendInfo();
        c.call();
        System.out.println("--------------");
        //智能
        AptitudeHandst a = new AptitudeHandst();
        a.info("IPHONE11","苹果");
        a.newWork();
        a.play("没有共产党,就没有新中国");
        a.takePicture();
        a.sendInfo();
        a.call();

    }
}
这是一款型号为GB121的小辣椒手机
开始播放音乐《啦啦啦》
开始发送文字信息.......
开始语音通话.......
--------------
这是一款型号为IPHONE11的苹果手机
已经启动移动网络
开始播放视频《没有共产党,就没有新中国》
咔嚓.....拍照成功
开始发送带图片与文字信息.......
开始视频通话.......

总结

  1. 抽象度:接口>抽象类>类>对象
  2. 抽象类不能显示调用构造方法,不能直接创建对象,但可以在子类调用构造方法时隐式被调用。
  3. 接口中只有抽象方法和静态方法,default方法,没有构造方法。
  4. 接口:提供连接外部组件的口子,理解为一个插口,插槽。所以属性和方法都必须是public
  5. 抽象类抽掉了对象的概念,接口进一步抽掉了类的概念。
  6. 接口中的属性没有set/get,也就是不能封装,是static final类型,因为接口已经不再可以理解成类,而是一个组件。组件的属性在出厂时就已经定型了。
  7. 多态的使用演变:
  8. Fu f=new Zi(); Fu是一个普通类
  9. Fu f=new Zi(); Fu是一个抽象类
  10. Fu f=new Zi(); Fu是一个接口,(使用最多)

你可能感兴趣的:(抽象类,接口,java)