接口是什么?
Interface是什么?
Java Interface是什么?
Java 接口是什么?
什么是Java接口?
Java接口是什么?
Java接口有什么作用?
Java接口的作用是什么?
Java Interface有什么用?
相信这是绝大多数Java初学者的困惑
面对这个疑惑, 甚至我可以说很多Java老司机也说不出来接口到底是什么? 有什么作用?
懵圈有没有?
你疑惑就对了, 你懵圈是正常的,
因为这个东西本来就是一团糟后给Java语言打上的一个补丁
不好理解是正常的
相信你自己, 你疑惑一个东西的时候
说明这个东西并不是什么好东西
比如给你写一篇文章, 官话套话一大堆,
中心思想不知道在哪里 让你疑惑了, 这篇文章好吗?
答案: 非常不好
我对接口的理解:
接口是一个对象暴露给外部功能集
其实就是Java语法过于严谨而打的一个补丁,主要目的为了解决单继承带来的问题,它是单继承的产物
为什么这么说, 我给你看一个例子你就明白了:
假设我有这么一个类:
//这是一个手机游戏里面的一个游戏角色
//它具有 x, y坐标 宽度width, 高度height
class Player extends A {
int getX() {...}
int setX(x) {...}
int getY() {...}
int setY(y) {...}
int getWidth() {...}
int setWidth(w) {...}
int getHeight() {...}
int setHeight(y) {...}
}
//我们有一个方法是让这个角色跳跃
void jump(Player player) {
//这里的代码只是例子
player.setX(player.getX() + 100)
player.setY(player.getY() + 500)
player ...
...半空中翻了三圈...
...手臂左边挥了一下, 再右边挥了一下...
...此处省去一万行代码....
...player 的引用在这段代码里面出现了5000次...
...总之假设这个方法非常复杂, 很多哈...
...
}
好了, 让这段代码跑起来
我们看到手机里的玩家开始正常地跳跃了
产品设计人员告诉我, 让我在手机里面加一个怪物,
这个怪物跟这个玩家跳跃的方式一一模一样
假设Java没有接口:
class Player extends A {
int getX() {...}
int setX(x) {...}
int getY() {...}
int setY(y) {...}
...
}
void jump(Player player) {
//这里的代码只是例子
player.setX(player.getX() + 100)
player.setY(player.getY() + 500)
player ...
...半空中翻了三圈...
...手臂左边挥了一下, 再右边挥了一下...
...此处省去一万行代码....
...总之这个方法非常复杂, 很多...
...
}
//我新加了一个怪物类
class Monster extends B {
int getX() {...}
int setX(x) {...}
int getY() {...}
int setY(y) {...}
...
}
Monster monster = new Monster()
jump(monster) 这里因为monster类型不匹配而报错, 不可以直接使用jump方法对monster实现跳跃
问题来了:
jump(monster) 这里因为monster类型不匹配而编译报错
我草jump代码一万行, 我昨天写了一整天加班到晚上23点才写完
我不可能重新写一个撒
而且
player extends A
monster extends B
而 A B 都是它们必须得继承的类,Java 又不支持多继承
怎么办? 怎么办? 简直束手无策,没有办法了
于是我只能完全复制一份jump方法, 并把所有的player改成monster:
void jump(Monster monster) {
//这里的代码只是例子
monster.setX(monster.getX() + 100)
monster.setY(monster.getY() + 500)
monster...
...半空中翻了三圈...
...手臂左边挥了一下, 再右边挥了一下...
...此处省去一万行代码....
...总之这个方法非常复杂, 很多...
...
}
Monster monster = new Monster()
jump(monster) 好了, 在这里我再调用jump方法, 完美实现了monster的跳跃
到这里, 功能是实现了, 但是完全复制这个方法这种做法, 肯定是非常错误的
重复的代码会埋下相当严重的隐患
于是Sun公司的Java的设计人员发现了这个问题,
并给这个问题打上了一个优雅的补丁: 接口Interface
我们可以定义一个接口 Spirit(精灵), 让Player和Monster都成为一个Spirit
interface Spirit {
int getX()
int setX(x)
int getY()
int setY(y)
}
//这是一个手机游戏里面的一个游戏角色
//它具有 x, y坐标
class Player extends A implements Spirit {
int getX() {...}
int setX(x) {...}
int getY() {...}
int setY(y) {...}
...
}
void jump(Spirit s) {
//这里的代码只是例子
s.setX(s.getX() + 100)
s.setY(s.getY() + 500)
s...
...半空中翻了三圈...
...手臂左边挥了一下, 再右边挥了一下...
...此处省去一万行代码....
...总之这个方法非常复杂, 很多...
...
}
class Monster extends B implements Spirit {
int getX() {...}
int setX(x) {...}
int getY() {...}
int setY(y) {...}
...
}
这样一来, 我们就只需要一个相同的jump方法, 就可以实现player和monster的跳跃功能了
一下子就提高了jump方法的重用性
完美的解决了代码重复的问题
这就是接口的核心作用
有人说, 接口是为了降低程序耦合度(什么鬼话)?不, 它跟耦合度没联系
又有人说, 接口强大(什么鬼话)?
它只是Java设计过于严谨而打的一个补丁,其目的是提高方法的重用性. 因为Java是单继承语言,如果没有接口,Java将无法正常使用
(不要去相信什么: “伟大的接口”, “强大的接口”… 这些花哨骗人洗脑写给小孩子看的广告词)
虽然接口作为参数的方法重用性更高,不代表你所有方法都要用接口来作为参数,毕竟多个接口多篇代码,大可不必过度使用,你有必要的时候再用不迟(eclipse自带从一个类抽取出接口的功能,推荐使用哟)
养成自顶向下的编码习惯, 你自然而然就会理解接口是什么
到这里, 你明白接口的核心作用了吗?
我对Interface(接口) 做了深入研究
最终还是有了伟大的发现!
你们知道Interface到底是什么吗? 作用是什么吗? 作用有多大?
Interface 象征 : 严谨 + 繁琐
Interface 是什么: 对象暴露给外部使用的功能集
Interface 作用: 所谓的降低类和类耦合度, 我说事实并不是这样的
Interface 作用有多大: 作用没多大
Interface 是严谨了, 但是它让Java代码量增多
Interface 是单继承产物, 因为单继承, 所以必须必须要有接口
我上面说到 “因为这个东西本来就是一团糟后给Java语言打上的一个补丁”
‘一团糟’ 说的是什么:
C++语言是一个多继承语言,多继承带来了非常多的问题
所以Java发现这个问题后, 就决定做个单继承的语言
没想到单继承也有很多无法实现的功能
所以就加上了接口这个东西, 完美解决了之前无法实现的功能
有接口了, 代码又增多了...就这样, 糟不糟?
我们不应该去依赖接口来降低耦合度, 或者说他跟耦合度根本沾不上边
想要降低程序耦合度, 我推荐大家应该多多使用一些设计模式:
这里我特别推荐一定要多多使用事件模式:
lady.on("fuck", function() {
bed.rock()
})
这是降低lady和bed间耦合度的非常好的办法!
降低耦合度的核心思想就是:
不要在bed类里面引用lady的对象
因为你在bed里面引用了lady的对象, 就相当于把一个lady插进了bed里面
lady哪里出了bug流了血可能把bed弄脏, 甚至把bed玩垮
而且你把lady插到bed里面也不符合客观事实, 想要把lady从bed里面拔出来的时候就很难了
写代码要符合人的正常思维
在这段代码里, 代码的耦合度关接口什么事? 半毛钱关系都没有
没接口的语言, 和有接口的语言比起来, 我总结了一下:
有没有接口, 都没关系, 都能完成我需要的功能
接口对项目经理还是有那么一点点用, 就是项目经理给你定义个接口, 叫你你你去给我把这个接口实现了今天就可以下班了
(但绝大多数项目经理并不会这么做, 没接口不代表这个工作就分配不下去了)
有接口就是写起来复杂点, 没有接口我照样不会犯错误…
接口我用得很多, 但接口并没给我带来太大好处, 真的没有
简单语法的编程语言,根本不需要接口
//这是一个手机游戏里面的一个游戏角色
//它具有 x, y坐标
class Player {
var x
var y
}
void jump(s) {
//这里的代码只是例子
s.x += 100
s.y += 500
s...
...半空中翻了三圈...
...手臂左边挥了一下, 再右边挥了一下...
...此处省去一万行代码....
...总之这个方法非常复杂, 很多...
...
}
class Monster {
var x
var y
}
player = new Player()
monster = new Monster()
jump(player)
jump(monster)
这些语言不必定义接口, 这段代码就可以正常运行, 是不是很厉害?
这个语言的开发者说, 咱们的语言方便简单, 不需要接口这种古怪的东西…