Java基础-接口及内部类

发布于 2024年07月27日

接口(interface)

概念

接口是一种规范,像我们在生活中的USB一样,如果一个USB厂商想要做U盘就要遵守操作系统提供的规范去做驱动程序实现USB与计算机的交互,接口与类的关系是实现关系,实现接口的类叫做实现类。

在类的继承之间是is a的关系,在接口则是能不能的关系。

定义接口

接口是抽象方法和常量值定义的集合。

接口的特点:

  • 接口定义用 interface 定义

  • 接口中所有的成员变量都是public static final

  • 接口中的抽象方法都是public abstract

  • 接口中没有构造器

  • 接口与接口之间是继承关系,并且支持多继承

interface MyInterface{
    //定义成员变量
    public static final String id;
    //public static final 可以省略
    String id1;
    
    //定义抽象方法
    public abstract void test1(){}
    //public abstract 可以省略
    void test2()
}

实现接口

接口的实现使用implements关键字,一个类可以实现多个接口。

实现接口是必须重写接口中所有的方法,否则类要定义为抽象类。

接口的主要用途就是被实现类实现。

接口和类是并列关系,可以理解为一种特殊的类

//实现接口
public ImplementsTest implements InterfaceTest{

    @Override
    public void test(){
        System.out.println("实现接口");
    }
}

interface InterfaceTest{
    void test();

}

抽象类和接口的对比

相同点:

  • 接口和抽象类都不能被实例化,被其他类实现和继承

  • 接口和抽象类都可以包含抽象方法,实现接口和继承抽象类的类都必须实现这些抽象方法,否则类要声明为抽象类

不同点:

  • 抽象类和接口的定义不同

  • 接口中只能包含抽象方法,不包含已经实现的方法(JDK 7.0之前),抽象类完全可以包含普通方法

  • 接口中不能定义静态方法(JDK 7.0之前),抽象类可以定义静态方法;

  • 接口只能定义静态常量属性,不能定义普通属性,抽象类里既可以定义普通属性,也可以定义静态常量

  • 接口不包含构造方法,抽象类中可以包含构造方法,抽象类的构造方法并不是用于创建对象,而是让继承的子类调用这些构造函数完成属于抽象类的初始化操作

  • 接口不包含初始化块,但是抽象类可以包含初始化块

  • 一个类最多只能有一个直接父类,包括抽象类,但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足

JKD 8.0/9.0 接口的改进

Java 8 中你可以为接口添加静态方法默认方法

静态方法:使用static关键字修饰。

默认方法:使用default关键字修饰。

私有方法:使用private关键字修饰。

public interface InterfaceUpdate{
    //JDK 8.0
    //静态方法   
    public static void test1(){}
    //public 可以省略
    static void test2(){}
    //默认方法
    public default void test3(){}
    //public 可以省略
    default void test4(){}
    
    //JDK 9.0
    //注意不可省略任何修饰
    private static void test5(){}

}

接口的冲突问题

方法中:

  • 接口冲突(左右为难):报错,让你必须重写指定(default)

  • 类优先原则:

直接调用super.method()会默认调用父类

调用父接口:接口.super.method()

常量:

  • 接口冲突:如果遇到同名的常量,则使用 接口名.常量名

内部类

概述

一个类定义位于另一个类的内部,前者称为内部类,后者称为外部类

分类:

  • 成员内部类(static成员内部类,非static成员内部类)

  • 局部内部类

成员内部类

作为类:

  • 可以在内部定义属性、方法、构造器等结构;

  • 可以声明为abstract类,因此可以被其他内部类继承;

  • 可以声明为final

  • 作编译后生成Outer$InnerClass.class字节码文件(也适用于局部内部类)

作为类的成员角色:

  • 和外部类不同,内部类还可与声明为privateprotected

  • 可以调用外部类的结构;

  • 内部类可以声明为static ,但此时就不能再使用外层类的非static的成员变量;

静态内部类和局部内部类创建对象:

public class Outer{
    public static void main(String[] args){
        //创建动态内部类
        Outer o = new Outer();
        Outer.DynamicInner od = o.new DynamicInner();
        //创建静态内部类
        Outer.StaticInner sd = new Outer.StaticInner();
    }
    //设置动态内部类
    public class DynamicInner{
    
    }
    //设置static内部类
    public static StaticInner{

    }
}

局部内部类

普通实现:

public class PartInner{
    public static void main(String[] args){
        class MyComparable implements Comparable{
            @Override
            public int compareTo(Object o){
                return 0;
            }
        }
        MyComparable mc = new MyComparable();
    }
}

匿名实现:

public class PartInner{
    public static void main() {
        Comparable mc = new Comparator() {
            @Override
            public int compare(Object o) {
                return 0;
            }
        };
    }
}



评论