1.什么是接口?


接口是一种抽象类型,定义了一组方法的规范,而不提供具体实现。接口可以被类实现,一个类可以实现多个接口,从而实现多重继承的效果

2.接口的特点


1.抽象方法:接口中的方法默认是抽象的(没有方法体)。
2.常量:接口中的变量默认是 public static final(常量)。
3.多重继承:一个类可以实现多个接口。

3.接口的实现和定义

// 接口定义
public interface Animal {
    void eat();
    void sleep();
}

// 类实现接口
public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    public void sleep() {
        System.out.println("Dog is sleeping");
    }
}

// 使用接口
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        dog.sleep();
    }
}

4.默认方法和静态方法(Java 8 引入)


默认方法:接口可以包含默认方法(有默认实现),类可以选择重写这些方法。

public interface Animal {
    void eat();
    void sleep();
    
    // 默认方法
    public default void run() {
        System.out.println("Animal is running");
    }
}

public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    public void sleep() {
        System.out.println("Dog is sleeping");
    }

    // 重写默认方法
    @Override
    public void run() {
        System.out.println("Dog is running");
    }
}

静态方法:接口可以包含静态方法,静态方法只能通过接口本身调用。static方法需要去掉default关键字

public interface Animal {
    void eat();
    void sleep();
    
    // 静态方法
    public static void info() {
        System.out.println("This is an Animal interface");
    }
}

public class Main {
    public static void main(String[] args) {
        // 调用接口的静态方法
        Animal.info();
    }
}

5.接口的优点

解耦:降低代码之间的依赖性,提高可维护性和可扩展性。
多重继承:通过接口实现多重继承,避免类继承中的菱形继承问题。
规范约定:接口定义了一组方法规范,强制实现类必须实现这些方法,保证一致性。

6.抽象类与接口的比较

特性抽象类接口
实例化不能实例化不能实例化
方法可以包含抽象方法和具体方法方法默认是抽象的(Java 8 之后可以有默认方法和静态方法)
成员变量可以有成员变量只能有常量(public static final)
构造函数可以有构造函数不能有构造函数
继承一个类只能继承一个抽象类一个类可以继承多个接口
访问修饰符方法和成员变量可以有不同的访问修饰符默认方法是public,不能有其他访问修饰符
适用场景定义类的基本结构和部分实现,适用于单一继承场景定义行为规范,适用于多重继承和解耦场景

7.接口中的private方法


在Java 9及以后的版本中,接口中可以定义私有方法。私有方法在接口中主要用于实现代码复用和封装细节,避免重复代码。它们不能被接口的实现类直接调用,只能在接口内部被其他默认方法或静态方法调用。
以下是一些关键点和示例:
接口中的私有方法和静态方法都不能用default修饰
私有实例方法:只能在接口的默认方法中调用。
私有静态方法:只能在接口的静态方法或默认方法中调用。

public interface MyInterface {

    // 默认方法
    default void defaultMethod() {
        System.out.println("Default Method");
        privateMethod();
    }

    // 静态方法
    static void staticMethod() {
        System.out.println("Static Method");
        privateStaticMethod();
    }

    // 私有实例方法
    private void privateMethod() {
        System.out.println("Private Instance Method");
    }

    // 私有静态方法
    private static void privateStaticMethod() {
        System.out.println("Private Static Method");
    }
}

public class MyClass implements MyInterface {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.defaultMethod(); // 调用默认方法
        MyInterface.staticMethod(); // 调用静态方法
    }
}

8. final的特点

修饰方法:表明该方法是最终方法,不能被重写
修饰变量: 表明该变量是常量,不能再次被赋值
如果修饰的是引用类对象(比如某个类的一个对象), 对象的数据可以修改, 但不能修改对象的内存地址. 而且要注意时机,最好是一开始就赋值, 最晚也要构造函数结束前复制

修饰类:表明该类是最终类,不能被继承
public static final String BOY = "男"

9.代码块

1. 局部代码块
位置:局部代码块位于方法内部。
特点:它们在方法被调用时按顺序执行,作用范围仅限于代码块内部。
作用:可以在方法内部使用局部变量,这些变量的作用域仅限于代码块内部,离开代码块后变量就会被销毁。

public void exampleMethod() {
    // 局部代码块
    {
        int x = 10;
        System.out.println("Value of x: " + x);
    }
    // x 在这里不可用
}

2. 构造代码块
位置:构造代码块位于类内部,但不在任何方法内。
特点:每次创建类的实例时执行。在每次构造方法之前执行。
作用:用于对象级别的初始化代码。可以用于初始化实例变量或执行需要在对象创建时完成的操作,无论调用哪个构造方法,构造代码块都会执行

public class ExampleClass {
    // 构造代码块
    {
        System.out.println("Instance initializer block executed.");
    }

    public ExampleClass() {
        System.out.println("Constructor executed.");
    }
}

3. 静态代码块
位置:静态代码块位于类内部,但不在任何方法内。
特点:静态代码块使用 static 关键字修饰。在类加载时执行,并且只执行一次。可以用于静态变量的初始化。
作用:用于执行类级别的初始化代码。通常用于初始化静态变量或执行需要在类加载时完成的操作。只会在类第一次被加载到内存时执行一次。

public class ExampleClass {
    static {
        // 静态代码块
        System.out.println("Static block executed.");
    }

    public ExampleClass() {
        System.out.println("Constructor executed.");
    }
}