Java接口和抽象类是什么,有什么区别

抽象(abstract)和接口(interface)在Java中都是关键字,也就说明他们足够重要,而抽象类和接口为我们面向对象编程提供了非常大的帮助。下面我们就一起来回顾这基础知识。

抽象类

  • 在构建某些未实现方法的类时,你可能会第一个想到接口,但是抽象类也是实现这个目的一种重要而必要的工具。
  • 创建抽象类需要用到abstract关键字来修饰类,我们希望通过这个通用的类操作一系类方法,如果没有具体的内容,这个抽象类的意义只有一个,就是不让其他类实例化这个抽象类的对象,只能实例化它的子类对象;要达到操控,Java给我们提供了抽象方法的机制,抽象方法也是使用abstract关键字来修饰,包含抽象方法的类就叫做抽象类

    抽象类特点

    • 1.抽象类和抽象方法必须用abstract关键字修饰
    • 2.抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者接口
    • 3.抽象类不能实例化,也就是说不能new出来,抽象类必须由子类实例化,这其实也就是多态的一种,抽象类多态(为什么抽象类不能实例化? 如果抽象类实例化,实例化的抽象类对象意思就可以调用抽象类的抽象方法,但是抽象方法是没有具体实现的,也就没有任何意义,所以抽象类不能实例化)
    • 4.抽象类的子类要么是抽象类(实例中的Car类),要么就重写抽象类中的抽象方法(实例中的Jetta类)
    • 5.一个类只能继承一个抽象类,抽象类也可以继承抽象类(实例中的SuperCar 类)

      抽象类成员特点:

    • 1.成员既可以是常量也可以是变量,但是abstract不能修饰成员变量,变量的值是不固定的,无法抽象
    • 2.抽象类也有构造方法,他的意义在于子类可以访问父类的初始化数据(实例中Jetta构造方法 super()调用了抽象父类构造方法)
    • 3.成员方法既可以抽象的,也可以是非抽象的,抽象方法一般是强制要求子类去实现的方法,非抽象方法一般是重复的代码,可以提高代码复用性
    • 4.abstract关键字不能与static关键字(原理和抽象类不能实例化其实是一个道理,staticx修饰的抽象方法不需要实例化可以直接调用,这显然是没有意义的)、final关键字(final修饰的方法子类不能重写,abstract修饰的方法子类强制重写)、private关键同时出现(private修饰的方法子类不能访问

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* @Author: mao.qitian
* @Date: 2018/8/11 0011 16:25
* @Description: 汽车抽象类
*/
public abstract class Car {

public Car(){
System.out.println("抽象类的构造方法被调用");
}

public void driver(){
System.out.println("所有汽车都能驾驶");
}
//汽车的速度
public abstract void speed();
}

/**
* @Author: mao.qitian@gxxmt.com
* @Date: 2018/8/11 0011 16:29
* @Description: 捷达
*/
public class Jetta extends Car{

public Jetta(){
super();
}

@Override
public void speed() {
System.out.println("开完兰博基尼再开捷达速度上无法适应");
}
}


/**
* @Author: mao.qitian
* @Date: 2018/8/11 0011 22:39
* @Description: 超跑
*/
public abstract class SuperCar extends Car {
//超跑的价格
public abstract void expensive ();
}

/**
* @Author: mao.qitian
* @Date: 2018/8/11 0011 16:27
* @Description: 兰博基尼
*/
public class Lamborghini extends SuperCar {
@Override
public void speed() {
System.out.println("兰博基尼速度两秒破百");
}

@Override
public void expensive() {
}
}

接口(interface)

  • 接口使抽象的更向前迈进了一步,interface关键字修饰方法产生的是完全抽象的类,它允许创建者定义方法名,传参和返回类型,但是它没有任何方法体,只提供了形式(规则),而未提供任何具体实现。

    接口的特点

  • 1.接口使用interface关键字代替class修饰类,
  • 2.类实现接口用implement表示
  • 3.和抽象类一样,接口也不能实例化,只能由实现了接口的类来进行实例化
  • 4.接口的子类可以是抽象类,也可以是具体类,具体类要重写接口的抽象方法

接口成员特点

  • 1.接口中定义的变量都是常量,默认修饰符为 public static final
  • 2.接口没有构造方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
    * @Author: mao.qitian
    * @Date: 2018/8/12 0012 0:22
    * @Description:
    */
    public interface A {
    public void b();
    }

    class C implements A{
    public C(){
    super();//调用的是Objetc类的构造方法,方法默认继承Objetc类
    }
    @Override
    public void b() {
    }
    }
  • 3.接口中的成员方法只能是抽象方法,默认修饰符为 public abstract

  • 4.接口中的所以成员方法和变量都是公共的(public)

接口的应用

  • 策略模式:定义一系列算法,把每一个算法封装起来,并且使他们可以相互替换。策略模式使得算法可独立于使用它的客户端而独立变化

    三个角色

  • 上下文角色(Context):操作我们制定策略的上下文环境,使用策略的通用调用
  • 抽象策略角色(Stragety):策略,算法的抽象,通常是一个接口
  • 策略的实现角色(ConcreteStragety):实现抽象的策略接口,具体实现这个策略

    实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
        实现学校教师的奖金发放,教师有属性:编号、姓名,教学总工作量,奖金
    奖金的计算方法为:
    x*30 (当职称为教授时)
    y= x*25 (当职称为副教授时)
    x*20 (当职称为讲师时)

    public interface Function {
    //接口定义抽象方法 (Stragety)
    public double Money(double x);
    }

    public class A implements Function {
    //教授奖金计算
    public double Money(double x) {
    return x*30;

    }

    public class B implements Function {
    //副教授奖金计算
    public double Money(double x) {
    return x*25;
    }
    }

    public class C implements Function {
    //讲师奖金计算
    public double Money(double x) {
    return x*20;
    }
    }
    public class myMoney {
    //上下文角色
    Function s;
    double M;//工时
    String name;//教师姓名
    String type;//教师职称
    int number;//教师编号

    public void S(double X,String N,int Num,String Type){
    this.M=X;
    this.name=N;
    this.number=Num;
    this.type=Type;
    }
    //奖金计算方式
    public double getMoney(){
    if(type.equals("教授")) s=new A();
    if(type.equals("副教授")) s=new B();
    if(type.equals("讲师")) s=new C();
    return s.Money(M);
    }
    }

    myMoney f=new myMoney();
    Scanner sc=new Scanner(System.in);
    System.out.println("请输入职位:");
    String Type=sc.next();
    System.out.println("请输入姓名:");
    String N=sc.next();
    System.out.println("请输入编号:");
    int Num=sc.nextInt();
    System.out.println("请输入工时:");
    double X=sc.nextDouble();
    f.S(X, N, Num, Type);
    System.out.println(N+奖金为"+f.getMoney());

类与类,类与接口,接口与接口之间的关系

  • 类与类之间,一个类只能继承一个类,但是类可以多层继承
  • 类与接口则是实现关系,一个类可以继承一个接口,也可以继承多个接口,也可以继承一个类的同时实现多个接口
  • 接口与接口之间是继承关系,一个接口可以继承另一个接口,也可以继承多个接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /**
    * @Author: mao.qitian
    * @Date: 2018/8/12 0012 0:22
    * @Description:
    */
    public interface A {
    public void a();
    }
    interface B {
    public void b();
    }
    interface C extends B,A{ //接口与接口之间继承,多继承
    public void c();
    }
    class D implements A,B,C{
    @Override
    public void a() { }
    @Override
    public void b() { }
    @Override
    public void c() { }
    }

抽象类和接口的区别

成员区别 继承关系区别 设计理念区别
抽象类 成员变量可以是常量,也可以是变量,有构造方法,成员方法可以是抽象的也可以是非抽象的 单继承,多层继承 被继承的体现是“is a”的关系,抽象类中定义的是该继承体系的共性功能
接口 成员变量只能是常量,没有构造方法,成员方法只能是抽象的 实现,可以实现多个接口 被继承的体现是“like a”的关系,接口中定义的是该继承体现的扩展功能

最后说点

  • 还是那句话,好记性不如烂笔头,通过这一篇文章,再次巩固了基础知识。如果文章中有写得不对的地方,请给我留言指出,大家一起学习进步。

  • 参考资料:

    • 《Android进阶之光》
    • 《Java编程思想》(第四版)
-------------本文结束感谢阅读-------------
0%