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 {@Overridepublic void defend() {System.out.println("防守赢得冠军");}@Overridepublic 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 {// 隐式的publicvoid defend();void attack();
}
复制代码
接口是隐式抽象的,所以声明时没有必要使用abstract
关键字;接口的每个方法都是隐式抽象的,所以同样不需要使用abstract
关键字;接口中的方法都是隐式public
的。
和抽象类一样,接口也不能直接被实例化,它需要一个类来实现它,就像以下示例展示那样。
class Hesai implements Coach {@Overridepublic void defend() {System.out.println("防守赢得冠军");}@Overridepublic void attack() {System.out.println("控球是把双刃剑");}
}public class Demo2 {public static void main(String[] args) {Coach moliniao = new Hesai();moliniao.defend();moliniao.attack();}
}
复制代码
实现一个接口需要用到关键字implements
,它表示:“我这个类遵从了接口的协议,如果你想使用我,看接口就行了,具体实现不用关心。”
03 多重实现
在现实生活中,何塞·穆里尼奥不止是一名足球教练,他还是一个值得被尊重的英雄——凭借自身的努力,他从一名籍籍无名的跟班翻译,逐渐蜕变为一名家喻户晓的顶级教练。
如果要在程序的世界里体现何塞·穆里尼奥的多重角色,就可以使用接口,就像以下示例展示那样。
package com.cmower.java_demo.nine.inf;interface Coach {// 隐式的publicvoid defend();void attack();
}interface Hero {void fight();
}class Hesai implements Coach, Hero {@Overridepublic void defend() {System.out.println("防守赢得冠军");}@Overridepublic void attack() {System.out.println("控球是把双刃剑");}@Overridepublic 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);}
}
复制代码
可以看到,创建的Hesai对象可以向上转型为Coach和Hero,然后调用各自接口中实现的具体方法,因为Hesai这个类同时实现了两个接口,分别是Coach和Hero(class Hesai implements Coach, Hero
,接口之间通过英文逗号隔开)。
04 接口在应用中常见的三种模式
在编程领域,好的设计模式能够让我们的代码事半功倍。在使用接口的时候,经常会用到三种模式,分别是策略模式、适配器模式和工厂模式。
1)策略模式
策略模式的思想是,针对一组算法,将每一种算法封装到具有共同接口的实现类中,接口的设计者可以在不影响调用者的情况下对算法做出改变。示例如下:
// 接口:教练
interface Coach {// 方法:防守void defend();
}// 何塞·穆里尼奥
class Hesai implements Coach {@Overridepublic void defend() {System.out.println("防守赢得冠军");}
}// 德普·瓜迪奥拉
class Guatu implements Coach {@Overridepublic void defend() {System.out.println("进攻就是最好的防守");}
}public class Demo {// 参数为接口public static void defend(Coach coach) {coach.defend();}public static void main(String[] args) {// 为同一个方法传递不同的对象defend(new Hesai());defend(new Guatu());}
}
复制代码
Demo.defend()方法可以接受不同风格的Coach,并根据所传递的参数对象的不同而产生不同的行为,这被称为“策略模式”。
2)适配器模式
适配器模式的思想是,针对调用者的需求对原有的接口进行转接。生活当中最常见的适配器就是HDMI(英语:High Definition Multimedia Interface,中文:高清多媒体接口)线,可以同时发送音频和视频信号。适配器模式的示例如下:
interface Coach {void defend();void attack();
}// 抽象类实现接口,并置空方法
abstract class AdapterCoach implements Coach {public void defend() {};public void attack() {};
}// 新类继承适配器
class Hesai extends AdapterCoach {public void defend() {System.out.println("防守赢得冠军");}
}public class Demo {public static void main(String[] args) {Coach coach = new Hesai();coach.defend();}
}
复制代码
Coach接口中定义了两个方法(defend()和attack()),如果类直接实现该接口的话,就需要对两个方法进行实现。
如果我们只需要对其中一个方法进行实现的话,就可以使用一个抽象类作为中间件,即适配器(AdapterCoach),用这个抽象类实现接口,并对抽象类中的方法置空(方法体只有一对花括号),这时候,新类就可以绕过接口,继承抽象类,我们就可以只对需要的方法进行覆盖,而不是接口中的所有方法。
3)工厂模式
所谓的工厂模式理解起来也不难,就是什么工厂生产什么,比如说宝马工厂生产宝马,奔驰工厂生产奔驰,A级学院毕业A级教练,C级学院毕业C级教练。示例如下:
// 教练
interface Coach {void command();
}// 教练学院
interface CoachFactory {Coach createCoach();
}// A级教练
class ACoach implements Coach {@Overridepublic void command() {System.out.println("我是A级证书教练");}}// A级教练学院
class ACoachFactory implements CoachFactory {@Overridepublic Coach createCoach() {return new ACoach();}}// C级教练
class CCoach implements Coach {@Overridepublic void command() {System.out.println("我是C级证书教练");}}// C级教练学院
class CCoachFactory implements CoachFactory {@Overridepublic Coach createCoach() {return new CCoach();}}public class Demo {public static void create(CoachFactory factory) {factory.createCoach().command();}public static void main(String[] args) {// 对于一支球队来说,需要什么样的教练就去找什么样的学院// 学院会介绍球队对应水平的教练。create(new ACoachFactory());create(new CCoachFactory());}
}
复制代码
有两个接口,一个是Coach(教练),可以command()(指挥球队);另外一个是CoachFactory(教练学院),能createCoach()(教出一名优秀的教练)。然后ACoach类实现Coach接口,ACoachFactory类实现CoachFactory接口;CCoach类实现Coach接口,CCoachFactory类实现CoachFactory接口。当需要A级教练时,就去找A级教练学院;当需要C级教练时,就去找C级教练学院。
依次类推,我们还可以用BCoach类实现Coach接口,BCoachFactory类实现CoachFactory接口,从而不断地丰富教练的梯队。
05 总结
尽管接口使得抽象更进一步,但任何抽象性都应该根据真正的需求而产生,因此恰当的原则是优先选择类而不是接口,只有在真正需要接口的时候再重构代码。
Java接口的实例应用:致敬我的偶像——何塞·穆里尼奥相关推荐
- 前端vue后端java,Vue调用后端java接口的实例代码_亦心_前端开发者
前段时间 做了个学校的春萌项目,其中用到 先上后端接口代码: package controller; import net.sf.json.JSONObject; import util.DBUtil ...
- vue.js 调用java_Vue.js调用后端java接口的实例代码
Vue.js调用后端java接口的实例代码 发布于 2020-11-30| 复制链接 分享一篇关于Vue调用后端java接口的实例代码,具有很好的参考价值,希望对大家有所帮助.一起跟随小妖过来看看吧 ...
- java接口的实例:打印工资单
import java.util.Scanner; /** 工资:基本工资,加班补助,奖金* 扣除:养老保险,医疗保险,还有超过5000的收个人所得税的3%* * * * **/ public cla ...
- java接口和实例_java – 接口和实例化
第二个声明是错误的: Then it goes on and says a paragraph or so later that "You can declare a variable to ...
- Java 接口基础详解,java开发面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
- Java的接口及实例
一.定义 Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为( ...
- 通过实例讲解java接口和抽象类的特殊实现方法
一.java中的接口本质上是加约束的抽象类 //抽象类 public abstract class AExample { public abstract int add(int x,int y): p ...
- Java的接口及实例(转)
转自:http://blog.csdn.net/liujun13579/article/details/7736116 一.定义 Java接口(Interface),是一系列方法的声明,是一些方法特征 ...
- java判断接口对象是哪个子类_Java提供了一个关键字( ),可以判断一个对象是否为某个类(或接口)的实例或者子类实例。...
Java提供了一个关键字( ),可以判断一个对象是否为某个类(或接口)的实例或者子类实例. 更多相关问题 -Do you know a has just opened in our neighborh ...
最新文章
- Python标准库——collections模块的Counter类
- 14,matlab中如何查看程序中所调用的函数
- phpmyadmi 上传大文件
- xfce4面板消失了解决方案+xfce4的面板保存设置以及读取
- 结构体变量和结构体指针变量作为函数参数传递问题
- 如何解除FSO上传程序小于200k限制?
- Hadoop HIVE 复合数据类型
- 决策树CART算法讲解
- 学一下HDFS,很不错(大数据技术原理及应用)
- Command line is too long. Shorten command line for Doc.generateAsciiDocs or
- Windows 2003 网络负载均衡的详细配置文档
- 使用dsoframer演示ppt
- 【安卓】3.修改列表增加下划线样式(保姆级图文+附示例)
- 输入日期判断这一年的第几天
- 51单片机 YF-S201水流量检测传感器的使用
- 解决win10开机内存过高的办法(亲测有效)
- 【BSV动态】VXPASS与世卫组织合作为莱索托提供数字疫苗监测服务
- 脑电波也能卖萌 这样的传感器好特别
- element的el-input-number的默认值的问题
- java中的码点_Java中码点和码点单元 码点与字符串的互化
热门文章
- 小程序判断一个对象是否为空 length不为0的空对象(空集合list)
- html div 区域,div全称division,意为“区分”。div标签被称为区隔标签,表示一块可显示 HTML 的区域。DIV的主要属性有( )...
- MomentJs 常用api
- 雅腾php怎么样_2018年09月26日
- 用递归实现求n!阶层和菲波那切数列
- 基于JQuery 改造bootstrap模态框拖动功能
- Win32汇编:过程与宏调用
- 监控系统zabbix
- CSS参考手册_web前端开发参考手册系列
- 限制7种范围IP的ASP自定义函数(改进)