In static OOP languages, interfaces are used in order to declare that several classes share some logical property - they are disposable, they can be compared to an int
, they can be serialized, etc.
Let's say .net
didn't have a standard IDisposable
interface, and I've just came up with this beautiful idea:
interface IDiscardable { void Discard(); }
My app uses a lot of System.Windows.Form
s, and I think that a Form
satisfies the logical requirements for being an IDiscardable
. The problem is, Form
is defined outside of my project, so C#
(and Java
, C++
...) won't allow me to implement IDiscardable
for it. C#
doesn't allow me to formally represent the fact that a Form
can be discarded
( and I'll probably end up with a MyForm
wrapper class or something.
In contrast, Haskell
has typeclasses
, which are logically similar to interfaces. A Show
instance can be presented (or serialized) as a string, Eq
allows comparisons, etc. But there's one crucial difference: you can write a typeclass instance (which is similar to implementing an interface) without accessing the source code of a type. So if Haskell
supplies me with some Form
type, writing an Discardable
instance for it is trivial.
My question is: from a language designer perspective, is there any advantage to the first approach? Haskell
is not an object oriented language - does the second approach violates OOP
in any way?
Thanks!
This is a difficult question, which stems from a common misunderstanding. Haskell type classes (TC), are said to be "logically similar" to the interfaces or abstract classes (IAC) from object-oriented programming languages. They are not. They represent different concepts about types and programming languages: IAC are a case of subtyping, while TC is a form of parametric polymorphism.
Nevertheless, since your questions are methodological, here I answer from a methodological side. To start with the second question:
does the second approach [that of extending the implementation of a class outside the class] violate OOP in any way
Object oriented programming is a set of ideas to describe the execution of a program, the main elements of an execution, how to specify these elements in the program's code, and how to structure a program so as to separate the specification of different elements. In particular, OOP is based in these ideas:
a
may at different states point to different objects.a
, the same field a.f
may at different states point to
different objects, which may belong to different classes. Thus, a
needs not to know to what class those objects b
belong; it only needs to know what messages do those objects accept. For this reason, the type of those fields can be an interface.
The interface declares a set of messages that an object can receive. The class specifies explicitly what interfaces are satisfied by the objects of that class.My answer to the question: in my opinion yes.
Implementing an interface (as suggested in the example) outside a class breaks one of these ideas: that the class of the object describes the complete set of messages that objects in that class can receive.
You may like to know, though, that this is (in part) what "Aspects", as in AspectJ, are about. An Aspect describes the implementation of a certain "method" in several classes, and these implementations are incorportated (weaved) into the class.
To answer back the first question, "is there any advantage to the first approach", the answer would be also yes: that all the behaviour of an object (what messages it answers to) is only described in one place, in the class.