Java 中的抽象类与接口

抽象类

如果一个类不能描绘一个具体的对象,那么这个类就是抽象类。
先来看下面这个例子:
示例
虽然 Animal 类中有 eat 方法,但是 Animal 的范围太广,不知道吃啥,所以不能具体实现 eat 的方法,所以可以将 Animal 类设计成抽象类,而 Dog 类,Cat 类和 Bird 类都可以具体实现 eat 方法(狗吃骨头、猫吃鱼、鸟吃虫子)。

像上面这个例子中,Animal 类中的 eat 方法没有具体实现什么功能,我们就可以把它设计成抽象方法,包含抽象方法的类称为抽象类

语法说明:
如果一个类被 abstract 修饰,那么这个类就是抽象类,抽象类中的方法被 abstract 修饰,那么这个方法就是抽象方法,抽象方法不用给出具体的实现细节(包括大括号)。例如下面这个类:

抽象类
注意:抽象类中也可以包含普通方法、属性、构造方法。


抽象类特点:

  1. 抽象类不能实例化
    不能实例化抽象类
  2. 抽象方法不能是 private 的
    抽象类不能是private
  3. 抽象方法不能被 final 和 static 修饰。 抽象方法需要子类重写,而 final 修饰的方法不能被重写,所以 abstract 和 final 不能同时使用。static 修饰的方法属于该类本身的,而这个方法又没有方法体,通过类再调用这个方法就会报错,所以 abstract 和 static 也不能同时使用。
    abstract不能和final,static使用
  4. 抽象类被继承后,子类需要重写父类中的抽象方法,除非子类也是抽象类。如果子类也是抽象类,那么抽象子类的子类就要重写父类的抽象方法。
    重写父类抽象方法
  5. 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。换句话说,一个方法是抽象方法,那么这个方法所在的类必须设置成抽象类。
  6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量。

可能看到这里还不清楚抽象类有什么用,功能和普通类都差不多。
其实抽象类的作用就是,当一个类继承了抽象类,那么这个类就知道它需要重写父类中的抽象方法,如果不重写,就会报错。而继承了普通类,子类不重写父类的方法,并不会报错,所以使用抽象类就相当于多一道保障。


接口

接口,在生活中是很常见的,比如插座,不管是冰箱还是电视,只要能插就能用。还有电脑上的 USB 接口,不管是鼠标还是键盘,同样能插进去就能用。上面的插座和 USB 接口,都是有一定的规范,所以接口就是公共行为的规范标准,只要符合这个标准,就是通用的。而 Java 中的接口是多个类的公共规范,是一种引用数据类型。


接口定义:

接口的定义和类的定义很像,将 class 关键字换成 interface 关键字即可。下面是接口声明的一个简单例子。

public interface 接口名称 {
    // 抽象方法
    public abstract void func1(); 
    // public abstract 是固定搭配,可以不写,也就是 func1和func2是一样的
    void func2();
    ...
}

接口使用:

接口并不能直接使用,需要一个类来实现(使用 implements 关键字)该接口,实现接口中的所有抽象方法。注意:implements 关键字放在 class 声明后面。

public class 类名称 implements 接口名称[, 其他接口名称, 其他接口名称..., ...]{

}

下面来看一个简单的例子:

在这里插入图片描述

注意事项:

  1. 接口类型是一种引用类型,但是不能直接实例化接口的对象。
    如上面的 Animal 接口,语句 Animal animal = new Animal(); 将会报错。
  2. 接口中的方法默认都是 public abstract,可以不用写。
    接口方法默认public
  3. 接口中的方法不能在接口中实现的,只能由实现接口的类来实现。因为接口里的方法是抽象方法,抽象方法不能有方法体。
    接口里的方法不能实现
  4. 重写接口中的方法时,不能使用默认的访问权限。
    重写接口方法不能使用默认权限
  5. 接口中如果有变量,那么就默认被 public static final 修饰(被 final 修饰,那么就需要指定初始值)。
  1. 接口中不能有构造方法和代码块。
    接口里不能有代码块

实现多个接口

在 Java 中,一个类只能继承一个类,但是可以实现多个接口。

我们先提供几个接口分别来表示 飞、跑、游泳。
几个接口


再创建几个类来实现这些接口:让狗类实现跑和游泳的接口,让鸭子实现上面三个接口( 飞、跑、游泳)。

Dog类:
实现多个接口

Duck类:
实现多个接口

运行效果:
运行效果

使用接口的好处就是我们不用关心类的具体类型,只注意这个类是否拥有接口里的功能。所以我们要想让狗具有飞的功能的话,就让狗实现飞的接口,这样狗就具有飞的功能了。

狗实现飞的接口

接口的多继承

在 Java 中,类的多继承是不合法,但接口允许多继承。例如:

interface Ifunc2 extends IRun,ISwim{

}

此时一个类实现 Ifunc2 接口的话,就需要重写 IRun 和 ISwim 里的方法。

public class Frog implements Ifunc2 {
    @Override
    public void run() {
        
    }

    @Override
    public void swim() {

    }
}

抽象类和接口的总结

  • 抽象类可以包含普通方法,这些普通方法子类可以不用重写直接使用,而接口不能包含普通方法,子类需要重写接口里的方法。
  • 抽象类里的普通方法可以提供方法的实现细节,而接口中只能存在public abstract 方法(JDK1.8以后允许有 default 和 static 修饰的方法)。
    接口里的默认方法和静态方法
  • 一个子类只能继承一个父类,但是可以实现多个接口,一个接口也能继承另一个接口。
  • 抽象类表示的是一种 is-a 关系(Dog is an …),而接口表示一种 has-a 关系(Dog has a …)。

注意: 如果几个类都有共同的方法,并且这个方法有一定的功能,我们就可以使用抽象类(抽象类里的普通方法可以有具体的实现)。如果想实现多重继承,我们就要使用接口,抽象类和接口之间有很多相似的地方,需要不断积累,才能选择出合适的。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值