c# - 禁止现有类的接口(interface)实现有什么好处吗?

标签 c# oop haskell interface programming-languages

在静态 OOP 语言中,使用接口(interface)来声明几个类共享一些逻辑属性 - 它们是一次性的,它们可以与 int 进行比较,它们可以被序列化,等等。

假设 .net 没有标准的 IDisposable 接口(interface),而我刚刚想出了这个绝妙的主意:

interface IDiscardable { void Discard(); }

我的应用使用了很多 System.Windows.Form,我认为 Form 满足成为 IDiscardable 的逻辑要求>。问题是,Form 是在我的项目之外定义的,所以 C#(和 JavaC++... ) 不允许我为它实现 IDiscardableC# 不允许我正式表示 Form 可以被丢弃 的事实(我可能会以 MyForm 包装类什么的。

相比之下,Haskell类型类,它们在逻辑上类似于接口(interface)。 Show 实例可以作为字符串呈现(或序列化),Eq 允许比较等。但是有一个关键的区别:你可以写类型类实例(类似于实现接口(interface)),无需访问类型的源代码。因此,如果 Haskell 为我提供了一些 Form 类型,为它编写一个 Discardable 实例就很简单了。

我的问题是:从语言设计者的角度来看,第一种方法有什么优势吗? Haskell 不是一种面向对象的语言 - 第二种方法是否以任何方式违反了OOP

谢谢!

最佳答案

这是一个难题,源于一个普遍的误解。 Haskell 类型类 (TC) 被认为与面向对象编程语言的接口(interface)或抽象类 (IAC) “在逻辑上相似”。他们不是。它们代表关于类型和编程语言的不同概念:IAC 是子类型的一种情况,而 TC 是参数多态的一种形式。

不过,既然你的问题是方法论的,我在这里从方法论的角度来回答。从第二个问题开始:

does the second approach [that of extending the implementation of a class outside the class] violate OOP in any way

面向对象编程是一组思想,用于描述程序的执行、执行的主要元素、如何在程序代码中指定这些元素,以及如何构建程序以分离不同的规范元素。特别是,OOP 基于以下思想:

  • 在任何执行状态下,进程(执行程序)都由一组对象组成。这个集合是动态的:它可能包含处于不同状态的不同对象,通过对象创建和销毁。
  • 每个对象 都有一个由一组字段表示的内部状态,其中可能包括对其他相关 对象的引用。关系是动态的:同一对象的同一字段a可能在不同的状态下指向不同的对象。
  • 每个对象都可以从另一个对象接收一些消息。收到消息后,对象可能会改变其状态,并可能会向其字段中的对象发送消息。
  • 每个对象都是一个的实例:该类描述了该对象有哪些字段、它可以接收哪些消息以及它在接收到消息后执行的操作。
  • 在一个对象a中,同一个字段a.f可能在不同的状态下指向 不同的对象,可能属于不同的类。因此,a 不需要知道那些对象 b 属于哪个类;它只需要知道那些对象接受什么消息。因此,这些字段的类型可以是接口(interface)。 该接口(interface)声明了对象可以接收的一组消息。该类明确指定该类的对象满足哪些接口(interface)。

我对这个问题的回答:我认为是的。

在类外部实现接口(interface)(如示例中所建议的那样)打破了以下想法之一:对象的类描述了该类中的对象可以接收的完整消息集。

不过,您可能想知道,这(部分)是 AspectJ 中的“方面”的含义。一个方面描述了某个“方法”在几个类中的实现,这些实现被合并(编织)到类中。

要回答第一个问题,“第一种方法有什么优势”,答案也是肯定的:对象的所有行为(它回答的消息)只在一个地方描述,在类。

关于c# - 禁止现有类的接口(interface)实现有什么好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25250534/

相关文章:

c# - 通过反射动态调用textboxfor

c# - 在构造函数中传递参数而不是设置属性

c# - C#、Java 中的变量作用域

haskell - 如何为类型级列表编写交集函数

c# - WPF 根据内容将标签背景设置为图像

c# - 如何在 C# 中使用ironPdf 将包含 SVG(可扩展矢量图形)图像的 html 文件转换为 pdf 文件?

c# - 无法在 GridView 中的行删除事件中获取单元格值

javascript - 在其他类中注入(inject)类

haskell - 返回 3 个参数中的最小偶数,如果没有偶数,则返回最大奇数

Haskell - 将坐标列表转换为 ASCII 图形?