Java中的接口和抽象类

一、介绍

  抽象类:被abstract修饰的类就可以称为抽象类。抽象类可以拥有抽象方法,也就是用abstract修饰的方法,这类方法没有具体的实现结构,只是一个定义。

  接口:用interface替换掉class形成的一个类似类的结构,接口里面的方法全是抽象方法,接口本身不实现任何功能。

二、抽象类

  抽象类本质还是一个类,它只是多了一个特点就是可以在抽象类里面定义抽象方法,此外抽象类不能被实例化,也就是不能创建一个运行类型位抽象类的对象,看下面的例子:

 1 class ceshi{
 2     public static void main(String[] args) {
 3         animal a1 = new animal();//报错
 4         Dog a3 = new Dog();
 5         a3.run();     
 6     }
 7 }
 8 abstract class animal{
 9   public void speak() {
10         System.out.println("this is an animal");
11     }
12     public abstract void run();
13 }
14 class Dog extends animal{
15     @Override
16     public void run() {
17         System.out.println("Dog is running");
18     }
19 }       

  可以看到animal是一个抽象类,它有一个抽象方法run,Dog类继承了抽象类animal,并且实现了抽象方法run,这里有几点要注意的:

1、抽象类animal中可以有自己已经实现的方法,如第9行的speak方法,继承抽象类animal的Dog类的对象是可以直接调用这个speak方法,这与普通的继承相同。Dog也可以自己重写这个speak方法。

2、抽象类中是可以没有抽象方法的,编译器不会报错,但如果有抽象方法,继承这个抽象类的普通类必须实现所有的抽象方法,不然会报错。如果不实现,也可以将自己也定义为抽象类。

3、抽象类是不能被实例化的,也就是说它不能出现在new的后面,编译器不能为一个抽象类来分配空间。上例第三行的报错

 

很明确的说明了被abstract修饰的抽象类是无法实例化的。

三、接口

  《java编程思想》中有这样一句话:“interface关键字使抽象的概念更向前迈进了一步”。

  在接口中任何方法都是抽象的,接口这个关键字产生了一个完全抽象的类,它根本不提供任何具体实现(上文抽象类允许拥有自己的视线方法),只允许创建者确定方法名、参数列表和返回类型。一个接口就可以让所有实现它的类看起来似乎都是一致的。

  我们同样看一个例子:

 1 class ceshi{
 2     public static void main(String[] args) {
 3         animal a1 = new animal();//报错
 4         Dog a3 = new Dog();
 5         a3.speak();
 6     }
 7 }
 8 
 9 interface animal{
10   public void speak() ;
11   public abstract void run();
12 }
13 class Dog implements animal{
14     public void speak() {
15        System.out.println("this is an Dog");
16     }
17     @Override
18     public void run() {
19         System.out.println("Dog is running");
20     }
21     
22 }

  可以看到,我把animal从一个抽象类转成了接口,同样由Dog类去实现(抽象类称为继承)这个接口,同样有几个点需要关注:

1、接口里面的方法前面其实默认有三个关键词:abstract、static、final,这三个是在接口中无条件存在的,所以注意第10行和11行的对比,11行的abstrct是冗余的,而我编译器也贴心的提醒我:

 

2、实现了接口的类同样也必须实现其中的抽象方法,而接口里面的方法都是抽象的,所以你必须实现接口里定义的全部方法。

3、接口中只能有抽象方法,不允许有方法体的方法。

4、同样接口也是不能实例化的,也就是第三行的报错,看一下报错的原因:

 

这可能有点熟悉,当我们尝试着去实例化抽象类的时候也是这样的提示,说明接口其实也是默认为一个抽象类,只不过它抽象的更加彻底。

 

那接口中可以存在常量嘛?其实是可以的:

1 public static void main(String[] args) {
2         System.out.println(animal.x);
3     }
4 
5 interface animal{ 
6     int x = 0;
7   public void speak() ;
8   public abstract void run();
9 }

  拿这个例子来说,我在animal接口里定义了一个常量,虽然我只是定义了它,但同上文所说,x是一个被static和final默认修饰了的静态变量(abstract只能修饰方法和类),所以我能在主函数中利用接口的名字去调用x的值,这与普通类中的静态变量是相似的,接口同样有其静态存储空间,静态变量就说存储在里面。

三、接口和抽象类的对比

最后贴一个总结:

 

 

posted @ 2021-12-02 19:04  空心小木头  阅读(379)  评论(0编辑  收藏  举报