重新总结 Java 中的接口

在之前的博客中,我有写到接口,但是还有一些语法没有总结到。本篇博客旨在于将接口拎出来单独总结。

一、接口

接口从某种意义上来说,就是完完全全的抽象类。

接口:由 interface 实现,如:

interface IA {

}

1. 接口的语法规则

① 接口中的普通方法,不能有具体实现,如果非要实现,需要被 default 修饰这个方法

② 接口中的所有方法的限定符都是 public,那么所有的方法都可以省略 public,而接口中的所有抽象方法的限定符都是 abstract public,那么所有的抽象方法同样可以省略 abstract public

③ 接口中的成员变量默认是被 public static final 修饰的,也就是说,接口中的成员变量必须被初始化

接口不可以通过 new 实例化对象

⑤ 如果一个类实现了一个接口,那么在这个类中,必须重写接口中所有的抽象方法,而且重写的抽象方法必须被 public 修饰(因为接口中的抽象方法默认是 public abstract)

⑥ 如果一个类 A 实现了接口 B,那么对应的代码格式为:

interface IB{

}

class A implements IB{

}

⑦ 一个类可以实现多个接口,然而一个类只能继承一个类

interface IX{

}

interface IY{

}

class Z{
    
}

class A extends Z implements IX,IY{
    
}

⑧ 两个接口之间使用 extends,表示一个接口拓展另一个接口。
注意下面代码,当类 A 实现了接口 IY ,类 A 必须重写两个方法。

interface IX{
    void func1();
}

interface IY extends IX{
    void func2();
}

class A implements IY{
    @Override
    public void func2() {

    }

    @Override
    public void func1() {

    }
}

2. 通过代码来演示接口的语法

在程序清单1中,我通过注释标明了接口使用时的一些语法规则,这十分重要!

程序清单1:

interface IShape{
    public int a; //error
    public static final int b = 10; //right
    int c = 20; //right
    
    public void func1(){ //error

    }
    
    default public void func2(){ //right

    }
    
    public static void write(){ //right

    }

    abstract public void draw1(){ //error

    }
    
    abstract public void draw2(); //right
    
    void draw3(); //right
}

public class Test {
    public static void main(String[] args) {
        IShape iShape = new IShape(); //error
    }
}

3. 继承与接口的综合

程序清单2:

class Animal{
    String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(){
        System.out.println(name + " 正在吃东西");
    }
}

interface IFlying{
    void fly();
}

class Bird extends Animal implements IFlying{
    public Bird(String name) {
        super(name);
    }

	//重写了接口中的方法
    @Override
    public void fly() {
        System.out.println(name + " 正在飞");
    }

	//重写了父类中的方法
    @Override
    public void eat() {
        System.out.println(name + " 正在喝蜂蜜");
    }
}

public class Test {
    public static void fly(IFlying iFlying){
        iFlying.fly();
    }
    
    public static void main(String[] args) {
        fly(new Bird("老鹰"));
        new Bird("蜜蜂").eat();
    }
}

输出结果:

out

对程序清单2 进行分析:

在程序清单2 中,我们演示了继承和接口,有几个语法点很关键:

① 在父类构造带参数的方法的同时,子类也需要构造同样的带参数方法。

public Bird(String name) {

}

② 在父类已有的普通成员方法情况下,子类却重写了父类的此方法,那么在编译时,系统直接使用子类重写的方法。

public void eat(){

}

③ 接口中的抽象方法是被 abstract public 修饰的,那么在一个类实现接口的时候,我们就必须对此抽象方法进行重写。

@Override
public void fly() {
	System.out.println(name + " 正在飞");
}

二、为什么有些代码 new 了一个接口

演示1

通常情况下,一个类实现了另一个接口,我们只能使用 implements 显示地表现出来,如下面的程序:

程序清单3:

interface IA{
    void test();
}

class B implements IA {
    @Override
    public void test() {
        System.out.println("我通过类 B 重写了接口的 test 方法");
    }
}
public class Test {
    public static void main(String[] args) {
        B b = new B();
        b.test();
    }
}

输出结果:

1

演示2

而我们知道接口是不能通过 new 来实例化对象的,但有时候我们也会看到【 new 接口 】的情况出现,但不会被编译器报错。因为这是一个匿名内部类实现接口的缘故,只是这个匿名类看起来被隐藏了一样,给人一种 new 了一个接口的错觉,而实际上匿名内部类实现了另一个接口,那么它依然需要重写接口中的抽象方法。所以,一个接口依然不能通过 new 实例化对象!

//语法格式

new + 接口名 + {

	//这里必须重写接口中的抽象方法!
	
};

通过下列程序来进行演示为什么可以这么做:

程序清单4:

interface IA{
    void test();
}

public class Test {
    public static void main(String[] args) {
        IA ia = new IA(){ //1
            @Override
            public void test() { //2
                System.out.println("我匿名重写了接口的 test 方法");
            }
        }; 

        ia.test();//3
    }
}

//注释
//1. 匿名类实现了接口 IA
//2. 匿名类重写了 test 方法
//3. 匿名类调用了 test 方法

输出结果:

2

演示3

程序清单4 又可以简化成程序清单5

程序清单5:

interface IA{
    void test();
}

public class Test1 {
    public static void main(String[] args) {
        new IA(){ //1
            @Override
            public void test() { //2
                System.out.println("我匿名重写了接口的 test 方法");
            }
        }.test(); //3
    }
}

//注释
//1. 匿名类实现了接口 IA
//2. 匿名类重写了 test 方法
//3. 匿名类调用了 test 方法

输出结果:

2

演示4

而程序清单5 又可以写成 Lambda 表达式

( (IA) () -> { System.out.println("我匿名重写了接口的 test 方法");} ).test();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十七ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值