深入理解 抽象类和接口

使用场景

当需要使得多个类看起来一样时,使用接口或者抽象类。
例如:当有四个类,分别为Basketball,Football,Baseball,Badminton。这四个类都有的方法为play(),stop(),pause(),这时可以把这些方法抽象出来,在抽象类中或者接口中声明,再让这四个类继承或实现。这样这四个类看起来就一样了。

抽象类

首先记住一句话,抽象类的存在是为了被继承,如果没有类继承它,它的抽象毫无意义。
使用步骤:
创建抽象类,包含抽象方法的类称为抽象类

abstract class Ball{
    public abstract void play();
    public abstract void stop();
    public abstract void pause();
}

抽象方法是没有方法体的,并且要用abstract修饰。

类继承抽象类:

class Basketball extends Ball{

    @Override
    void play() {
        //实现具体方法逻辑
    }

    @Override
    void stop() {
        //实现具体方法逻辑
    }

    @Override
    void pause() {
        //实现具体方法逻辑  
    }

}

创建抽象类和抽象方法非常有用,因为它可以使类的抽象性明确起来,并告诉用户和编译器打算怎么使用它们。

接口

接口使得抽象性更加明确,是比抽象类更抽象的存在,接口表示:“所有实现了该特定的接口的类都应该看起来这样”。
该注意的地方:
- 接口的方法默认是public,并且只能为public
- 接口也可以包含域,域默认是static和final的(SE5之后一般用enum,接口的 域一般不采用)
- 接口允许被向上转型,因此很灵活

使用步骤:
创建接口:

interface Ball{
    void play();
    void stop();
    void pause();
}

类实现接口:

class Basketball implements Ball{

    @Override
    public void play() {
        //实现具体方法逻辑
    }

    @Override
    public void stop() {
        //实现具体方法逻辑
    }

    @Override
    public void pause() {
        //实现具体方法逻辑  
    }
}

为什么使用接口

接口存在的意义在哪?或者说使用接口有什么好处,仅仅是让它们看起来一样会不会太牵强?
看看下面这个例子:

class Ball{
    public String play(){
        return getClass().getName()+" play";//返回类的名字
    }
}

class Basketball extends Ball{
    @Override
    public String play() {
        return super.play();
    }
}

public class Test{

    public static void use(Ball ball){
        System.out.println(ball.play());
    }

    public static void main(String[] args){
        use(new Basketball());
    }
}

例子很容易理解,就是打印出继承了哪个类调用了play这个方法(实际情况会更复杂的需求),还有Football之类这里就不写出来了。但是更好的方式是使用接口,即让Ball成为一个接口。为什么明明类可以实现,却用接口实现更好?

想想当你用上述的代码完成了一个项目,项目中大量使用到了块代码,假如有一天,一个名叫 Paino 的类,你也想知道它的名,那你怎么办?
方法1:再写一个play()方法,但是假如又有其它的类,也要获取名字呢?难道你要写一个又一个的方法吗?这样会很多冗余代码!
方法2:让 Paino 继承Ball,那假如你已经无法修改这个类了呢?例如Paino已经继承了其他的类。

这是你是不是束束手无策了?假如使用接口呢?

interface Ball{
    String play();
}

class Basketball implements Ball{

    @Override
    public String play() {
        return "Basketball play";
    }

}

public class TestInterface {

    public static void use(Ball ball){
        System.out.println(ball.play());
    }

    public static void main(String[] args){
        use(new Basketball());
    }

}

使用接口的情况下,Paino也需要调用play这个方法,无论Paino有没有继承其他类或者实现其他接口,都能再实现Ball,因为接口是多实现的。这样一看就知道为什么使用接口了吧!

使用接口的原因

  1. 能够减少耦合,避免大量的冗余代码,并且能够后期更加灵活地修改,使代码更具有复用性。
  2. 能够上转型为多个基类型,以及带来的灵活性。
  3. 跟抽象类的作用一样,放置程序员创建该类的对象。

什么时候使用抽象类和接口

如果要创建不带任何方法定义和成员变量的基类,应该使用接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值