Java 抽象类和接口,看这一篇就够了(1)

本篇来谈谈 Java 的抽象类和接口。


曹操在《短歌行》中为杜康酒打过一个价值一亿个亿的广告——“何以解忧,唯有杜康”,我替曹操感到惋惜的是他本人并不会收到这笔不菲的代言费。想一想,要是三国时期的明星人物们有这个代言意识的话,保证各家的军费收入会多出来一个重量级的来源。


不过,酒真的能解忧吗?我不大敢相信。李白就曾质疑过:“举杯消愁愁更愁,抽刀断水水更流。”我和李白持相同的观点,酒啊,真的不容易解忧,但绝对可以增加作者莫名的写作冲动。


我在写本篇之前就小酌了一杯,一不小心激发了我强烈的创作欲望。不过我要奉劝各位,寒冬之际,如果遇到烦心事,千万别肆意地追求一醉方休,万事要懂得适可而止。


01、 抽象类


一种比较苍白的说法是:在 Java 中,通过关键字 abstract 定义的类叫做抽象类。Java 是一门面向对象的语言,因此所有的对象都是通过类来描述的;但反过来,并不是所有的类都是用来描述对象的,抽象类就是其中的一种。


以下示例展示了一个简单的抽象类:


// 个人认为,一名教练必须攻守兼备
abstract class Coach {
    public abstract void defend();
    public abstract void attack();
}

在一个抽象类中,至少有一个抽象方法(通过关键字 abstract 定义的方法,并且没有方法体,如上例中的 defend() 方法和 attack() 方法),否则就没有必要称之为抽象类。需要注意的是,抽象类是不能实例化的! 它需要被一个子类继承,就像以下示例那样。

abstract class Coach {
    public abstract void defend();

    public abstract void attack();
}


class Hesai extends Coach {

    @Override
    public void defend() {
        System.out.println("防守赢得冠军");
    }

    @Override
    public void attack() {
        System.out.println("控球是把双刃剑");
    }
}

public class Demo {
    public static void main(String[] args) {
        Coach moliniao = new Hesai();
        moliniao.defend();
        moliniao.attack();
    }
}


我们都知道,一个好的教练,必须攻守兼备,但每个教练的进攻理念和防守理念不尽相同。因此,我在教练这个抽象类(Coach)中定义两个抽象方法,一个进攻(attack)一个防守(defend),这两个方法的具体实现都要由抽象类的子类确定,抽象类本身并不负责。


我们也都知道,何塞·穆里尼奥是足球界的*教练。他是我最爱的足球教练,没有之一。尽管他在曼联的失败有他自身的原因,但我依然崇拜他,因为:“请不要说我傲慢,因为我只是实话实说,我是欧洲冠军,因此我并非籍籍无名,而是特殊的一个!”他是固执的反控球主义者,坚信控球是把双刃剑,防守赢得冠军。


好了,对于抽象类我们简单总结一下:


1、抽象类不能被实例化。

2、抽象类应该至少有一个抽象方法,否则它没有任何意义。

3、抽象类中的抽象方法没有方法体。

4、抽象类的子类必须给出父类中的抽象方法的具体实现,除非该子类也是抽象类。


02、 接口


我们知道,有抽象方法的类被称为抽象类,也就意味着抽象类中还能有不是抽象方法的方法。这样的类就不能算作纯粹的接口,尽管它也可以提供接口的功能——只能说抽象类是普通类与接口之间的一种中庸之道。


接口(英文:Interface),在 Java 中是一个抽象类型,是抽象方法的集合;接口通过关键字 interface 来定义。接口与抽象类的不同之处在于:


1、抽象类可以有方法体的方法,但接口没有。

2、接口中的成员变量隐式为 static final,但抽象类不是的。

3、一个类可以实现多个接口,但只能继承一个抽象类。


以下示例展示了一个简单的接口:

// 隐式的abstract
interface Coach {
    // 隐式的public
    void defend();
    void attack();
}


实现一个接口需要用到关键字 implements,它表示:“我这个类遵从了接口的协议,如果你想使用我,看接口就行了,具体实现不用关心。”


03、 实现多个接口


在现实生活中,何塞·穆里尼奥不止是一名足球教练,他还是一个值得被尊重的英雄——凭借自身的努力,他从一名籍籍无名的跟班翻译,逐渐蜕变为一名家喻户晓的*教练。


如果要在程序的世界里体现何塞·穆里尼奥的多重角色,就可以使用接口,就像以下示例展示那样。

package com.cmower.java_demo.nine.inf;

interface Coach {
    // 隐式的public
    void defend();
    void attack();
}

interface Hero {
    void fight();
}


class Hesai implements Coach, Hero {

    @Override
    public void defend() {
        System.out.println("防守赢得冠军");
    }

    @Override
    public void attack() {
        System.out.println("控球是把双刃剑");
    }

    @Override
    public void fight() {
        System.out.println("只要一息尚存,就应该战斗到最后");
    }
}

public class Demo2 {
    public static void defend(Coach coach) {
        coach.defend();
    }
    
    public static void fight(Hero hero) {
        hero.fight();
    }
    
    public static void main(String[] args) {
        Hesai moliniao = new Hesai();
        defend(moliniao);
        fight(moliniao);
    }
}

上一篇:OpenCV学习(23) 使用kmeans算法实现图像分割


下一篇:【AdaBoost算法】基于OpenCV实现人脸检测Demo