我曾多次看到有人提到这一点,但我不清楚这是什么意思。你什么时候,为什么要这么做?
我知道接口是做什么的,但我不清楚这一点的事实使我认为我错过了正确使用它们。
如果你要这样做
IInterface classRef = new ObjectWhatever()
你可以使用任何实现IInterface的类吗?你什么时候需要这样做?我能想到的唯一一件事是,如果你有一个方法,你不确定什么对象将被传递,除了它实现IInterface。我不知道你需要多久做一次。
另外,如何编写一个方法来接受实现接口的对象呢?这可能吗?
即使当我们不依赖于抽象时,面向接口编程也是有利的。
接口编程迫使我们使用对象的上下文适当的子集。这很有用,因为它:
防止我们做一些不合时宜的事,还有
让我们在将来安全地更改实现。
例如,考虑实现Friend和Employee接口的Person类。
class Person implements AbstractEmployee, AbstractFriend {
}
在这个人的生日的情况下,我们编程到朋友界面,以防止像对待员工一样对待这个人。
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
在这个人的工作环境中,我们对雇员界面进行编程,以防止模糊工作场所的边界。
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
太好了。我们在不同的环境中都有适当的表现,我们的软件运行良好。
在遥远的未来,如果我们的业务改变为与狗打交道,我们可以相当容易地更改软件。首先,我们创建一个实现Friend和Employee的Dog类。然后,我们安全地将新的Person()更改为新的Dog()。即使两个函数都有数千行代码,这个简单的编辑也可以工作,因为我们知道以下是正确的:
Function party只使用Person的Friend子集。
函数workplace只使用Person的Employee子集。
类Dog实现了Friend和Employee接口。
另一方面,如果任何一方或工作场所都针对Person进行编程,就会有同时拥有特定于Person的代码的风险。从“人”改为“狗”需要我们梳理代码,删除任何“狗”不支持的“人”特定代码。
寓意:为接口编程可以帮助我们的代码适当地运行,并为更改做好准备。它还使我们的代码能够依赖于抽象,这带来了更多的好处。
即使当我们不依赖于抽象时,面向接口编程也是有利的。
接口编程迫使我们使用对象的上下文适当的子集。这很有用,因为它:
防止我们做一些不合时宜的事,还有
让我们在将来安全地更改实现。
例如,考虑实现Friend和Employee接口的Person类。
class Person implements AbstractEmployee, AbstractFriend {
}
在这个人的生日的情况下,我们编程到朋友界面,以防止像对待员工一样对待这个人。
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
在这个人的工作环境中,我们对雇员界面进行编程,以防止模糊工作场所的边界。
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
太好了。我们在不同的环境中都有适当的表现,我们的软件运行良好。
在遥远的未来,如果我们的业务改变为与狗打交道,我们可以相当容易地更改软件。首先,我们创建一个实现Friend和Employee的Dog类。然后,我们安全地将新的Person()更改为新的Dog()。即使两个函数都有数千行代码,这个简单的编辑也可以工作,因为我们知道以下是正确的:
Function party只使用Person的Friend子集。
函数workplace只使用Person的Employee子集。
类Dog实现了Friend和Employee接口。
另一方面,如果任何一方或工作场所都针对Person进行编程,就会有同时拥有特定于Person的代码的风险。从“人”改为“狗”需要我们梳理代码,删除任何“狗”不支持的“人”特定代码。
寓意:为接口编程可以帮助我们的代码适当地运行,并为更改做好准备。它还使我们的代码能够依赖于抽象,这带来了更多的好处。