Java 中, new 对象时,用接口作为接收变量到底有什么好处呢?

2019-08-16 14:03:46 +08:00
 Wangjl

这个问题百度了很多一直也没看明白,百度上各种文章写的也不太清晰。

有没有通俗易懂白话,来讲讲到底有什么好处

例如

接口类型 变量 = new 实现类();

实现类类型 变量 = new 实现类();
8320 次点击
所在节点    Java
80 条回复
xuanbg
2019-08-17 08:49:46 +08:00
1、我只需和你约定接口有哪些方法,分别是什么参数,你就可以在我没有提供实现的情况下愉快的写代码了,不必等我写完逻辑再开始。
2、同一个接口可以在不同的情况下使用不同的实现,这样,你只需在构造的时候传一个正确的实现类就行,下面的逻辑都是一样的,就不用写长长的 if/else。
arthas2234
2019-08-17 10:04:10 +08:00
最直白的:多态,解耦
去看下 Java 关于容器的实现,你会有一个清晰的认识
macemers
2019-08-17 10:04:43 +08:00
我的意见是,首先,放弃使用百度,排除一下困难直接使用 google。其次,放弃使用中文术语,尽量使用英文术语。养成这样的习惯,之后学习编程才比较容易

这样的问题你可以 google 例如 why interface is over/better than concrete object/implemetation in Java
vincel
2019-08-17 11:01:55 +08:00
@pisc 我猜大家不想回你都是觉得浪费时间吧 java 你给我 var 一个看看好吗
hanxiaomeng
2019-08-17 11:34:59 +08:00
假定有如下方法:
```
public static void test(Animal a) {
a.print();
}
public static void test2(Cat c) {
c.print();
}
```
现在有一个 Cat 类:
```
test(new Cat());
test2(new Cat());
```
某一天我添加了 Dog:
```
test(new Dog());
//test2(new Dog());
```
hanxiaomeng
2019-08-17 11:39:10 +08:00
@hanxiaomeng 接口的存在就是为了实现更强大的多态,提高程序的可扩展性。理解多态,理解可扩展性,自然就理解接口了。
pisc
2019-08-17 11:54:29 +08:00
@vincel 大哥,是你无知还是我无知你不会查一查吗?你这样很尴尬啊,我都不知怎么回你了,var 是 Java10 的 feature 好吗?
aguesuka
2019-08-17 11:57:49 +08:00
因为 java 代码自带文档,按下点的一瞬间,你能调那些方法 idea 已经帮你算好了
pisc
2019-08-17 12:01:27 +08:00
@vincel Java 社区乌烟瘴气就是因为你这种摇头晃脑满口设计模式其实半瓶水晃荡毛都不懂的人导致的
nicevar
2019-08-17 12:15:17 +08:00
很多人说的太抽象了不容易理解,这个问题从实际应用上来说明比较好看懂,举个例子,比如你的软件要对接不同的广告系统,百度、腾讯、阿里的等,你在你的项目里面 new 不同的广告对象把所有的广告 sdk 搅在一块不是特别蠢么?所以你只需要在自己的项目中增加一个广告模块,抽象好共同特征的接口,这样无论他们的 sdk 怎么变动,你的项目无需修改,只需要动一下对接各个 sdk 的实现就行了,而且发布不同的版本也非常方便。
Sasasu
2019-08-17 13:21:59 +08:00
> 比如你的软件要对接不同的广告系统,百度、腾讯、阿里的等

不同的广告系统支持的功能是不同的,没干过广告,拿推送举例。

Apple 不允许系统的得知这个设备 UUID 是不是失效了,用户有没有卸载程序,只能推送文字并发出特定声音。
Android 允许系统探测用户有没有卸载程序,推送可以多行 带图,并能发出特定声音。

Android 又有好几家推送的 vendor, 支持的特点也不相同,技术特性比如 webp 支持,业务特性比如 PNG 转成 jpg 时透明背景是白色还是黑色,还是能根据手机的主题转换。

如果你有一个 interface 那么你只能在所有的推送系统中取子集,Android 系统的推送只有一行文字。

请做个实验,看看两种推送那种打开率高,再考虑你要不要把所有推送抽象成 interface,还是让运营明白她发出去的推送在不同手机上展示的效果究竟是什么样子的。
你要卖一个推送产品,那种卖的更好?
Sasasu
2019-08-17 13:29:10 +08:00
可能这个推送 SDK 支持最好的平台是 BB 机,但是 BB 能组播,智能机不能组播。大概是个不能组播的 BB 机推送 SDK
nicevar
2019-08-17 13:53:50 +08:00
@Sasasu 你没看明白意思,我说的对接广告系统是指客户端展示,无论你是哪一家的广告 SDK,做的功能无非就是开屏广告、浮层、banner、native 这些广告展示方式,因此只需要抽象这些共同点做成统一接口就行了。
Sasasu
2019-08-17 16:10:52 +08:00
于是你的广告 sdk 只支持 “开屏广告、浮层、banner、native ” 并且广告的渲染层和业务的渲染层解耦,导致广告出来的总比业务慢半秒,还经常挡住业务按钮
Sasasu
2019-08-17 20:56:56 +08:00
https://tanronggui.xyz/t/588729#reply7

> 收到非 200 抛异常,按照返回码注册处理函数,发不出带 body 的 get,发不出带 urlencode 的 post put,multipart/form-data 不能带字符串甚至只能放文件,把数组用任何方式序列化在 urlencode 里,不跟随 302,不关心 connection close 的 HTTP client 都应该去死

这就是 Java 的 interface 带来的间接影响
nnnToTnnn
2019-08-18 01:32:40 +08:00
当你这样写代码的时候,就没啥吊意义了

接口类型 变量 = new 实现类();
实现类类型 变量 = new 实现类();

如果在没有 ioc 框架的情况下

() => (className){
Class clazz = Class.forName(className);
接口类型 变量 = constructor.newInstance();
}

或者直接用 ioc 框架,例如 spring


接口的目的是为了隔离与实现类的关系,这下好了,都是强依赖了。


主要是为了后期动态切换实现类,而不用过多的修改项目结构
nnnToTnnn
2019-08-18 01:37:09 +08:00
@vincel var 只是一个特性,Java 无论在那个版本 var 都是一个保留关键字。 你这样说估计可能太了解 Java
nnnToTnnn
2019-08-18 01:43:32 +08:00
其次所谓的接口,抽象类等等,都没有屌用。没有这些东西一样能开发出一个健壮的系统。

当你去写代码的时候,可以思考下,这个我为什么要用这个设计模式,可以为我带来什么优点,以及缺点是否可以忍受。


团队接受水平 and 项目复杂程度 and 自己理解

不要为了设计模式而去设计模式。 比如很简单的一个例子


例如

```
接口类型 变量 = new 实现类();

实现类类型 变量 = new 实现类();
```

> 如果这个实现类,并不重要,且以后不会有多大的变化,是否用接口进行动态其实意义并不大


```
实现类 变量 = new 实现类();

实现类 变量 = new 子实现类();
```

一样可以用继承的方式进行强制转换。
ccxml
2019-09-24 15:22:27 +08:00
看着舒服,一个几千行的 class 只需要看他的接口就能知道个大概,省事
ccxml
2019-09-24 15:23:46 +08:00
特别是维护旧代码的时候,有接口没接口区别老大了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/592462

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX