Java 接口赋值的模式探索

来源:互联网 发布:windows tv box 编辑:程序博客网 时间:2024/05/17 07:36

实际上,我也不太清楚这到底是什么,但目前来说只是找到了一个例子去解释这种实现方式(至于这个例子恰当与否,还有待探索)。

public class TestMain {public static void main(String[] args) {Thing thing = new Thing();thing.iMoveAction = new MoveThing();System.out.println(thing.iMoveAction.isAnimal(new Object()));}}interface IMoveAction {void move();boolean isAnimal(Object object);}class Thing {IMoveAction iMoveAction;}class MoveThing implements IMoveAction {@Overridepublic void move() {// TODO 自动生成的方法存根}@Overridepublic boolean isAnimal(Object object) {// TODO 自动生成的方法存根return false;}}

当时,我是有这样的疑问,thing.iMoveAction是IMoveAction的接口对象,而new 出来的MoveThing()是一个实现了IMoveAction接口的MoveThing的类,为何能将一个类赋值给一个接口对象呢?(实际上联想到List list = new ArrayList<>();的例子,也就可以对这种方式习以为常。但终究是无法清晰地解释这种方式。)

由此涉及到对接口定义的思考,什么是接口?

接口是规范、规则、公共的要去统一实现的内容。


那么我可以这样理解:thing对象中有iMoveAction这样的一个规则对象,而new出来的MoveThing实际上也是拥有这样一个规则对象的。thing.iMoveAction= new IMoveThing();实际上做的就是——>将new出来的MoveThing()对象的规则赋值给thing.iMoveAction这个规则的对象,可以称之为“规则的移植复用”。

举个现实生活中的例子:国乒有自己的一套标准规则,国际上也是有乒乓球的标准规则的。但是因为国乒的强大,国际的乒乓球标准规则就套用了国乒的标准规则。此时,假设国乒是new出来的MoveThing(),国际是Thing对象。国乒(MoveThing)实现了的标准规则,现在被国际(拥有thing.iMoveAction对象)拿来用了。

所以此处,最后输出的内容thing.iMoveAction.isAnimal(new Object())实际输出的是MoveThing中isAnimal实现的方法的内容(也就是国乒定的标准规则)。


class Panda extends Thing{}
若此时再定义一个Panda类,然后进行以下代码运行:

Thing thing3 = new Thing();thing3.iMoveAction = (IMoveAction) new Panda();System.out.println(thing3.iMoveAction.isAnimal(new Object()));
可以看到Panda类没有实现IMoveAction接口,只是继承了Thing类,所以在进行thing3.iMoveAction赋值时,编辑器会提示要么给new Panda()对象强制转换类型,要么让Panda类实现IMoveAction接口。此处选择了强制转换,编辑器没有报错,但——>运行时会提示转换类型错误,这个是很显然的,毕竟new出来的Panda()对象没有实现IMoveAction接口。

那么疑问出来了,Panda类只是没有实现IMoveAction接口,但是却拥有IMoveAction对象呀,为啥就不能赋值了呢?

——>还是使用乒乓球的例子:Panda类可以比作是国乒:国乒拥有一套“标准规则”,但只是私下的,并没有明文规定出来(也就是没有作为一套必定执行的标准去实现),那么国际上如果要拿去用,当然是不会被国际上那些不同国家的乒乓理事成员所承认的。所以,此处是不通过的,国乒得首先按照这套标准规则去明文实现才行(也就是Panda类首先得implements IMoveAction接口才行)。


当然,若某个子标准规则是继承了父标准规则,那么子标准规则也是可以用来给“实现了父标准规则的类的标准规则对象”赋值的。

interface ICrawlAction extends IMoveAction{int moveDistance();}class Snake implements ICrawlAction{@Overridepublic void move() {// TODO 自动生成的方法存根}@Overridepublic boolean isAnimal(Object object) {// TODO 自动生成的方法存根return true;}@Overridepublic int moveDistance() {// TODO 自动生成的方法存根return 3;}}

此时ICrawlAction继承了IMoveAction,并定义了新的方法moveDistance()(相当于增加了规则)。此时Snake类实现了这个ICrawlAction接口,之后运行:

Thing thing4 = new Thing();thing4.iMoveAction = new Snake();System.out.println(thing4.iMoveAction.isAnimal(new Object()));

结果是:true。

可以看到,虽然ICrawlAction对IMoveAction进行了继承,但是并不影响对IMoveAction的对象赋值,因为赋值的时候使用的是“部分规则移植复用”,并不是全部,只要有相同的规则部分,均可以拿来使用。


ok,到此为止,以上例子为个人解释,或有不妥,欢迎探讨。若有不爽,憋着。