本文问题的兄弟问题 https://segmentfault.com/q/1010000040306308 我提的问题父类 x = new 子类();的意义

List list = new ArrayList<>();
多年来令我费解
这个问题的不同问法有为什么面向接口编程?

插曲
实现接口的方法一定要声明为public,因为接口中定义的方法都是默认为public(可以省略不写)的。

这个回答讲的很好烦人的苍蝇和烦人的电话推销员的例子
但是他讲的是为什么要用接口 不能回答上面的问题 L l=new AL;
https://stackoverflow.com/a/384067

我惊讶地发现实现了同一个接口的两个类居然都可以放进参数声明为借口的方法中
这么基本的功能我现在才意识到
比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
比如
IPest[] iPestsArr=new IPest[]{telemarketer1,telemarketer2,houseFly1,houseFly2};

再比如
IPest就是恼人行为的接口

void inviteIPestOnly(IPest iPest) {
iPest.BeAnnoying();
}

class HouseFly implements IPest

HouseFly houseFly1 = new HouseFly();

diningRoom.inviteIPestOnly(houseFly1);

接口可以被理解成弱化的继承。
他也是一种分类手段,当不同类的对象(电话推销员、苍蝇)表现出相同特征(恼人)时通过这个特征来分类。
原文:I finally understood their use as a language construct by thinking of them as a means of classifying common traits or behaviors that were exhibited by potentially many non-related classes of objects.

插播下策略模式
interface Fly, interface highhighFly extends Fly, interface landFly extends Fly

1
2
3
4
5
6
7
8
9

public abstract class Duck {
protected FlyBehavior flyBehavior;
public void performFly()
{
flyBehavior.fly();
}

}

定义下策略模式:定义了算法族(陆地飞、高高地飞),分别封装起来让他们可以相互替换。让算法的变化独立于使用算法的客户(各种duck)。

这样做的好处之一
这个设计在 DiningRoom 和各种 Pests 之间耦合得足够松散,你可以引入新的害虫(想想 class Covid19 implements IPest {…};!),在编写 DiningRoom 类时甚至不存在!您不仅不需要更改Diningroom,甚至不需要重新编译它!在测试和大型项目中派上用场

但是上面的写法仅仅解释了为什么用接口 而没有解释
HouseFly houseFly1 = new HouseFly();
InterfaceAnnoying houseFly1 = new HouseFly(); 两种写法的区别。在这里例子里两种写法都ok。

同问题下一个更切题的答案
stackoverflow.com/a/383982/9868445

我在v2ex上提问
https://www.v2ex.com/t/829411#reply26

感觉说的比较好的是

限定只能用 List 的方法。
只用和只能用还是有点区别的,这么写最大好处是防手滑。

代码防御; 可以让后面调用的人,只能调用接口声明的方法,而不会误调用 具体实现的某些公开方法。
在后续,如果要切换具体的实现,只要替换 new ArrayList 即可,对调用方无感知。

个人提炼:我从一开始 List=new AL 下面我每次用到list的时候都不会碰AL专属的方法。 如果我AL=new AL了 就可能不小心用了一个AL专属方法
以后再改成linkedList就不好改了