JavaSE-09 【抽象类和接口】

文章详细阐述了Java中抽象类和接口的概念、格式、使用方法以及注意事项。抽象类用于定义不能直接实例化的类,包含抽象方法,子类必须实现所有抽象方法。接口作为规范标准,可以包含抽象方法、默认方法、静态方法和常量,从Java8开始支持默认方法和静态方法,Java9引入了私有方法。文章还讨论了接口间的多继承和与类的继承关系。
摘要由CSDN通过智能技术生成

JavaSE-09 【抽象类和接口】

第一章 抽象类

1.1 抽象的概念

抽象:是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。具体地说,抽象就是人们在实践的基础上,对于丰富的感性材料通过去粗取精、去伪存真、由此及彼、由表及里的加工制作,形成概念思维形式,以反映事物的本质和规律的方法。

其实说白了,抽象就是把事物的共同特征总结为一点。 他和具体又是相对的。就比如说“男人”对于“人类”是具体的,而“动物”对于“人类”又是抽象的。抽象—》抽出相同特征的对象,他也有个同义词叫归类。

1.2 抽象类和抽象方法的格式

抽象类:抽象方法所在的类,必须是抽象类,在class前加一个abstract关键字

抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束

/**
 * 抽象类:抽象方法所在的类,必须是抽象类,在class前加一个abstract关键字
 * 抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束
 */
public abstract class Animal {
    //这是一个抽象方法,代表吃东西,但是具体吃什么,大括号中的内容不确定
    public abstract void eat();

    //这是一个普通的成员方法
    public void method(){

    }
}

1.3 抽象类和抽象方法的使用

  • 使用步骤:
    • 1、不能直接new抽象类的对象
    • 2、必须用子类继承抽象父类
    • 3、子类必须覆盖重写父类当中所有的抽象方法,即重写时去掉abstract关键字,补充上方法体大括号
    • 4、创建子类对象进行使用
/**
 * 抽象类:抽象方法所在的类,必须是抽象类,在class前加一个abstract关键字
 * 抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束
 * 使用步骤:
 *  1、不能直接new抽象类的对象
 *  2、必须用子类继承抽象父类
 *  3、子类必须覆盖重写父类当中所有的抽象方法,即重写时去掉abstract关键字,补充上方法体大括号
 *  4、创建子类对象进行使用
 */
public abstract class Animal {
    //这是一个抽象方法,代表吃东西,但是具体吃什么,大括号中的内容不确定
    public abstract void eat();

    //这是一个普通的成员方法
    public void method(){

    }
}
public class Cat extends Animal{
    //重写父类的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃老鼠");
    }

/**
 * 测试抽象类
 */
public class TestAbstract {
    public static void main(String[] args) {
        //创建实现类对象
        Cat cat = new Cat();
        //调用方法
        cat.eat();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZsHUHnx-1686205722653)(photo/JavaSE09_抽象类和接口.assest/1664812707347.png)]

1.4 抽象类和抽象方法的注意事项

  • 1、抽象类不能创建对象,如果创建编译错误,只能创建抽象类的非抽象子类的对象

  • 2、抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的

    ​ 子类的构造方法中,有默认的super(),需要访问父类的构造方法

  • 3、抽象类中,不一定包含抽象方法,但是有抽象方法的类一定是抽象类

  • 4、抽象类的子类,必须重写抽象父类中的抽象方法,否则,编译错误,除非该子类也是抽象类

第二章 接口

2.1 接口概述

接口:就是一种公共的规范标准,只要符合规范标准,就可以调用。

比如电脑的USB口就是一种规范,符合规范的标准的前提下,鼠标,键盘,U盘等都可以调用

2.2 接口定义的基本格式

  • 接口:是多个类的公共规范,接口是一种引用数据类型

  • 格式:

public interface 接口名称{
    //接口内容
}
  • 接口中可以包含的内容:

    • 常量 java7
    • 抽象方法 java7
    • 默认方法 java8
    • 静态方法 java8
    • 私有方法 java9
  • 接口使用的三步骤

    • 1、接口不能直接使用,必须有一个实现类实现接口
    • 2、接口的实现类必须重写接口中所有的抽象方法。即去掉abstract关键字,添加方法体
    • 3、创建实现类对象即可使用
    • 格式:
    public class 实现类名称 impletements 接口名 {
        //实现类的内容
    }
    

2.3 接口抽象方法定义

  • 定义抽象方法
    • 格式:public abstract 返回值类型 方法名(参数列表)
    • 注意事项:
      • 1、接口中的抽象方法,修饰符必须是两个固定的关键字:public abstract
      • 2、这两个关键字修饰符,可以选择性的省略,省略任意一个或者全省都可以

2.4 接口抽象方法使用

/**
 * 1、定义抽象方法
 *    格式:public abstract 返回值类型 方法名(参数列表)
 *    注意事项:
 *      1、接口中的抽象方法,修饰符必须是两个固定的关键字:public abstract
 *      2、这两个关键字修饰符,可以选择性的省略,省略任意一个或者全省都可以
 */
public interface InterfaceAbstract {
    public abstract int method1();
    public void method2();
    abstract String method3();
    int method4();
}
/**
 * 2、实现类
 */
public class InterfaceAbstractImpl implements InterfaceAbstract{
    @Override
    public int method1() {
        System.out.println("第1个抽象方法");
        return 0;
    }

    @Override
    public void method2() {
        System.out.println("第2个抽象方法");
    }

    @Override
    public String method3() {
        System.out.println("第3个抽象方法");
        return null;
    }

    @Override
    public int method4() {
        System.out.println("第4个抽象方法");
        return 0;
    }
}
/**
* 3、测试
*/
public class TestInterfaceAbstract {
    public static void main(String[] args) {
        //创建实现类对象
        InterfaceAbstractImpl impl1 = new InterfaceAbstractImpl();
        //调用方法
        impl1.method1();
        impl1.method2();
        impl1.method3();
        impl1.method4();
    }
}

2.5 接口默认方法定义

  • 接口中默认方法(从java8开始)
  • 格式
public default 返回值类型 方法名称(参数列表){
    //方法体
}
  • 主要事项:
    • 1、public可以缺省不写,但是default必须写
    • 2、接口中的默认方法可以解决接口升级的问题
    • 3、默认方法可以被接口的实现类直接调用,也可以被实现类重写之后调用

2.6 接口默认方法使用

/**
 * 1、接口中默认方法(从java8开始)
 *  格式:
 *      public default 返回值类型 方法名称(参数列表){
 *          //方法体
 *      }
 *  注意事项:
 *      1、public可以缺省不写,但是default必须写
 *      2、接口中的默认方法可以解决接口升级的问题
 */
public interface InterfaceDefault {
    //1、抽象方法
    public abstract int method1();

    //2、在此接口的实现类已经投入使用的情况下,需要升级接口,
    //   按照惯性思维,需要添加一个抽象方法,实现类也需重新实现,不切实际
    //public abstract void method2();

    //3、新添加的方法,使用默认方法形式,实现接口升级,同时已投入使用的实现类可以直接使用
    public default void methodDefault(){
        System.out.println("我是新添加的默认方法");
    }
}
/**
 * 2、实现类A
 */
public class InterfaceDefaultImplA implements InterfaceDefault{
    @Override
    public int method1() {
        System.out.println("第一个抽象方法的实现");
        return 0;
    }
}
/**
 * 实现类B
 */
public class InterfaceDefaultImplB implements InterfaceDefault{
    @Override
    public int method1() {
        System.out.println("第一个抽象方法的实现");
        return 0;
    }

    @Override
    public void methodDefault() {
        System.out.println("我是新添加的默认方法被重写");
    }
}
/**
* 4、测试
*/
public class TestDefault {
    public static void main(String[] args) {
        //创建接口实现类对象
        InterfaceDefaultImplA implA = new InterfaceDefaultImplA();
        //调用方法
        implA.method1();
        //调用接口新增的默认方法,如果实现类中没有,则会向上找接口
        implA.methodDefault();

        System.out.println("----------------");

        InterfaceDefaultImplB implB = new InterfaceDefaultImplB();
        //调用方法
        implB.method1();
        //调用重写的默认方法
        implB.methodDefault();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jgbIBKeB-1686205722654)(photo/JavaSE09_抽象类和接口.assest/1664873584907.png)]

2.7 接口静态方法定义

  • 接口中定义静态方法(从java8开始)

    • 格式:
    public static 返回值类型 方法名(){
        //方法体
    }
    
  • 注意事项

    • 1、方法上有static关键字修饰
    • 2、静态方法有方法体
    • 3、public可以省略
    • 4、不能使用接口的实现类来调用接口中的静态方法

2.8 接口静态方法使用

/**
 * 1、接口中定义静态方法(从java8开始)
 *  格式:
 *      public static 返回值类型 方法名(){
 *          //方法体
 *      }
 *  注意事项:
 *      1、方法上右static关键字修饰
 *      2、静态方法有方法体
 *      3。public可以省略
 *      4、不能使用接口的实现类来调用接口中的静态方法
 */
public interface InterfaceStatic {
    //接口中定义静态方法
    public static void methodStatic(){
        System.out.println("我是接口中的静态方法");
    }
}
/**
 * 2、实现类
 */
public class InterfaceStaticImpl implements InterfaceStatic{

}
/**
 * 3、测试
 */
public class TestStatic {
    public static void main(String[] args) {
        //创建实现类对象
        InterfaceStatic impl = new InterfaceStaticImpl();
        //不能使用接口实现类对象直接调用接口中的静态方法
        //impl.methodStatic();

        //需要使用接口名.静态方法名,进行直接调用
        InterfaceStatic.methodStatic();
    }
}

2.9 接口私有方法定义

  • 接口中定义私有方法(从java9开始)
  • 1、普通私有方法:解决多个默认方法之间重复代码问题,重复代码提取到普通私有方法中
    • 格式:private 返回值类型 方法名称(参数列表){方法体}
  • 2、静态私有方法:解决多个静态方法之间重复代码问题,重复代码提取到静态私有方法中
    • 格式:private static 返回值类型 方法名称(参数列表){方法体}

2.10 接口私有方法使用

/**
 * 接口中定义私有方法(从java9开始)
 *  1、普通私有方法:解决多个默认方法之间重复代码问题,重复代码提取到普通私有方法中
 *      格式:private 返回值类型 方法名称(参数列表){方法体}
 *  2、静态私有方法:解决多个静态方法之间重复代码问题,重复代码提取到静态私有方法中
 *      格式:private static 返回值类型 方法名称(参数列表){方法体}
 */
public interface InterfacePrivateA {
    public default void methodDefaultA(){
        System.out.println("默认方法A");
        methodAB();
    }
    public default void methodDefaultB(){
        System.out.println("默认方法B");
        methodAB();
    }
    //共性的内容存放在私有方法中
    private void methodAB(){
        System.out.println("私有普通AAAA");
        System.out.println("私有普通BBBB");
    }
}
/**
 * 接口中定义私有方法(从java9开始)
 *  1、普通私有方法:解决多个默认方法之间重复代码问题,重复代码提取到普通私有方法中
 *      格式:private 返回值类型 方法名称(参数列表){方法体}
 *  2、静态私有方法:解决多个静态方法之间重复代码问题,重复代码提取到静态私有方法中
 *      格式:private static 返回值类型 方法名称(参数列表){方法体}
 */
public interface InterfacePrivateB {
    public static void methodDefaultA(){
        System.out.println("静态方法A");
        methodAB();
    }
    public static void methodDefaultB(){
        System.out.println("静态方法B");
        methodAB();
    }
    //共性的内容存放在私有静态方法中
    private static void methodAB(){
        System.out.println("私有静态AAAA");
        System.out.println("私有静态BBBB");
    }
}
/**
 * 实现类A
 */
public class InterfacePrivateAImpl implements InterfacePrivateA{

}

/**
 * 实现类B
 */
public class InterfacePrivateBImpl implements InterfacePrivateB{

}
/**
 * 测试类
 */
public class TestPrivate {
    public static void main(String[] args) {
        //创建A类接口的实现类对象
        InterfacePrivateAImpl implA = new InterfacePrivateAImpl();
        //调用方法
        implA.methodDefaultA();
        implA.methodDefaultB();

        System.out.println("-----------------");

        //接口B名称直接调用静态方法
        InterfacePrivateB.methodDefaultA();
        InterfacePrivateB.methodDefaultB();

    }
}

在这里插入图片描述

2.11 接口的常量定义和使用

  • 接口中可以定义“成员变量”,也就是常量

    • 这个成员变量必须使用public static final 三个关键字进行修饰,这其实就是接口中的常量

    • 格式: public static final 数据类型 常量名称 = 常量值;

    • 注意事项:

      • 1、一旦使用final关键字修饰,就不可以改变

      • 2、接口中的常量必须赋值

      • 3、接口中常量的名称必须使用全部大写

      • 4、接口中的变量总是需要定义为“ public static final 变量类型 变量名 = 变量值;”,

        ​ 但可以不包含这些修饰符,编译器默认会添加这些限制

        ​ 因为接口是不可能有直接实例的,那样的话也就不可能修改(final),

        ​ 同样也不可能通过实例访问的(static)

public class InterfaceConst {
    //这其实就是一个常量,一旦赋值,不可以修改
    public static final int NUM = 100;
    //常量的修饰符可以缺省
    int NUM2 = 200;
}
/**
 * 测试:访问接口中的常量
 */
public class TestConst {
    public static void main(String[] args) {
        //使用接口名.常量名访问
        System.out.println(InterfaceConst.NUM);
    }
}

2.12 接口内容总结

在Java9版本中,接口的内容可以有:

  • 1、接口中的常量
    • 成员变量其实是常量,格式:public static final 数据类型 常量名称 = 数据值;
    • 常量必须进行赋值,而且一旦赋值不能修改
    • 常量名完全大写,用下划线进行分隔
    • public static final 修饰符可以缺省
  • 2、接口中的抽象方法
    • 格式:public abstract 返回值类型 方法名称 (参数列表);
    • public abstract 可以缺省
    • 实现类必须重写接口中的全部抽象方法,否则,除非实现类是抽象类
  • 3、从Java8开始,接口中可以定义默认方法
    • 格式: public default 返回值类型 方法名称(参数列表) {方法体}
    • public关键字可以缺省,但是abstract不能缺省
    • 默认方法可以被接口实现类直接调用,也可以在实现类中重写
  • 4、从Java8开始,接口中可以定义静态方法
    • 格式 : public static 返回值类型 方法名称 (参数列表) {方法体}
    • public可以缺省,static不能缺省
    • 只能通过接口名进行调用,不能使用接口的实现类对象进行调用
  • 5、从Java9开始,接口中允许定义私有方法,保罗普通私有方法和静态私有方法
    • 普通私有方法:private 返回值类型 方法名称(参数列表){方法体}
    • 静态私有方法:private static 返回值类型 方法名称(参数列表){方法体}
    • private修饰的私有静态方法只有接口自己才能调用,接口的实现类对象不能调用

2.13 继承父类并实现多个接口

接口的使用注意事项:

  • 1、接口不能被实例化,且其是没有构造方法的
  • 2、接口没有静态代码块的
  • 3、一个类的直接父类是唯一的,但是一个类可以同时实现多个接口
  • 4、如果在实现多个接口,不同接口中有重名的抽象方法,实现类中只重写一次
  • 5、如果实现类中没有重写所有接口当中的所有抽象方法,那么实现类必须是一个抽象类
  • 6、如果接口中存在重名的抽象方法,那么实现类必须要对冲突的默认方法进行重写
  • 7、父类的优先级大于接口。
    • 如果一个类继承了父类A,同时实现了接口B,父类中的方法与接口中的默认方法
      重名产生冲突,优先使用父类中的方法。
public interface InterfaceA {
    public abstract void methodA();
    //接口之间抽象方法重名
    public abstract void methodSame();
    //接口之间默认方法重名
    public default void methodDefault(){
        System.out.println("默认方法AAA");
    }
}
public interface InterfaceB {
    public abstract void methodB();
    //接口之间抽象方法重名
    public abstract void methodSame();
    //接口之间默认方法重名
    public default void methodDefault(){
        System.out.println("默认方法BBB");
    }
}
public class InterfaceImpl implements InterfaceA,InterfaceB{
    @Override
    public void methodA() {
        System.out.println("重写了接口A的抽象方法");
    }

    @Override
    public void methodB() {
        System.out.println("重写了接口B的抽象方法");
    }

    @Override
    public void methodSame() {
        System.out.println("重写AB接口中都有的重名抽象方法,只写一个即可");
    }

    @Override
    public void methodDefault() {
        System.out.println("实现类必须重写接口中重名冲突的默认方法,只写一个即可");
    }
}
public class TestInterfaceAB {
    public static void main(String[] args) {
        InterfaceImpl impl = new InterfaceImpl();
        impl.methodA();
        impl.methodB();
        impl.methodSame();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pgKIfXMU-1686205722655)(photo/JavaSE09_抽象类和接口.assest/1664883841425.png)]

2.14 接口之间的多继承

接口与类的关系:

  • 1、类与类之间是单继承的,直接父类唯一
  • 2、类与接口之间是多实现的,一个类可以实现多个接口
  • 3、接口与接口之间是多继承的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值