【问题标题】:Is the purpose of an interface to hide information?界面的目的是隐藏信息吗?
【发布时间】:2011-06-07 00:43:32
【问题描述】:
鉴于接口也用于帮助隐藏信息,因此只为用户提供了他们被允许使用的可能方法的一个子集,并且假设我有一个 Person 类和接口 IPerson。
现在主要,我可以这样做
IPerson testy = new Person();
或
Person testy = new Person();
所以实际上我仍然不受使用 Person 的限制。那么界面是如何真正隐藏数据的呢?
【问题讨论】:
标签:
c#
oop
interface
information-hiding
【解决方案1】:
如果你没有 Person 类怎么办。
Object obj = loadObject();
if(obj is IPerson) {
IPerson person = (IPerson) obj;
}
或
IPerson person = loadPerson();
【解决方案2】:
接口本身不用于“隐藏”任何内容。它用于在调用者和实现之间建立契约。该合约承诺“这些方法和属性会在这里,并且不会改变”。
接口也为改变实现提供了很好的可能性,而无需调用者处理它。这在解耦设计中至关重要。
您的问题暗示您的main 想要了解有关Person 课程的所有信息。你实际得到的是耦合代码,这更难测试。要“解决”这个问题,您必须改变思维方式并思考:main不想了解Person 的一切,它只对IPerson 感兴趣并且只需要界面。不多不少。
【解决方案3】:
您的误解来自“隐藏信息”的含义。无论您从谁那里听到这句话的意思是,实现一个接口允许一个类将其前向方法与其内部实现分开。
这也称为“封装”,它的好处是允许设计人员更改对象的内部机制,而不会破坏围绕其公共接口编写的现有代码,从而更容易进行更改。因此,您会经常听到将接口描述为“契约”,因为它在用户和类的实现者之间创建了一种隐含的协议,即其前向方法将保持一致。而且由于多个类可以实现一个接口,一个组件可以很容易地被另一个组件替换,只要它实现相同的公共接口。 Grady Booch 是一本备受推崇的面向对象设计书籍的作者,他对封装的定义如下:
划分构成其结构和行为的抽象元素的过程;封装用于分离抽象的合同接口及其实现。
对象的消费者不必知道或暴露于该对象的设计者如何在幕后实现其功能。想想你的微波炉:使用微波炉制作零食所需要做的就是按下前面的几个按钮。这就是您的微波炉的公共接口。不必仅仅为了制作一袋爆米花而了解其设计背后的科学原理。接口在这里的好处是它们降低了复杂性并使其他开发人员更容易使用您的类。
因此,回到您问题中给出的示例,您不应该被限制使用 Person 类,但您可能会受限于您能够访问的该类公开的方法。例如,Person 类可能在内部将一个人的姓名存储在单独的 FirstName 和 LastName 字段中,但只公开公开一个 Name 属性,该属性返回这两个私有姓名字段的串联。
但是面向对象的设计和术语相当复杂。我强烈建议您搜索一本关于这些概念的好书并仔细阅读。因为它,你会成为一个更好的程序员。
【解决方案4】:
.net 中接口的基本不能做任何其他方式的目的是提供有限形式的多重继承。让一个类从另一个类继承有两个正交的目的:
- 这意味着能够充分满足派生类需求的基类的字段、方法和属性可以被派生类使用,而无需重新指定。
- 这意味着期望基类方法的代码可以自动使用派生类的方法。
.net 中的类不可能隐式使用多个基类的成员,但一个类可以实现许多接口,并且可以替换其中的任何一个。例如,字典和链表没有太多共同之处,但它们都可以枚举。串口和 ListBox 没有太多共同点,但都可以 Disposed。
几乎所有接口可以做的事情,都可以用抽象基类做的更好或更好。接口可以做而基类不能做的一件事是允许有限形式的多重继承。