[fpc-devel] interfaces vs classes in dll
Graeme Geldenhuys
graemeg.lists at gmail.com
Fri Nov 30 11:19:20 CET 2007
On 30/11/2007, Michael Schnell <mschnell at lumino.de> wrote:
> >
> What is the advantage of interfaces anyway (seems that I have been
> missing something ... )
>
Many others have answered this already, so I'm not going to type out
the answer. Instead, I'll just quote some of them.... This should
give you plenty of information ;-)
-------------------------
Inheritance = I am
Aggregation = I have
Interface = I can
Examples:
01: Inheritance
Both a company and a person are a legal entity. I might want to descend
them both from an abstract LegalEntity class.
02: Aggregation
An employee is not a type of person. A person may perform multiple
roles such as Employee, Supplier, Customer, and so on.
03: Interface
Your application may wish to access certain services such as
IDataImporter, IDataExporter or IReportGenerator etc. There is no
point in having these descend from a common base class at all, instead
your app would just be provided with a reference to any object that
implements the correct interface. This interface would then operate
according to the requirements of the interface when the application
executes methods of that interface. Another benefit of this is that
one class might actually implement more than one interface, so it
could import/export data and also generate a data
report.
Peter Morris
-------------------------
Any class, no matter in which hierarchy, can implement an interface. So
your objects do not have to descend from TSomeClass to be used.
Class inheritance hierarchies are useful if you can reuse code from the
base class. But if you need a capability any class in any hierarchy
might have (like being printable, or being serializable, or being some
kind of list, or being able to provide certain data) it makes much more
sense to use interfaces.
Usually, interfaces should be very simple, only exposing a simple
capability of a certain class, so it doesn't take much to implement
them. But you can also think of interfaces like IList, or IEnumerable,
where any class that has a list-like indexed structure, or can be
enumerated, respectively, implements the appropriate interface. These
classes do not have to be part of a certain hierarchy, especially if
that doesn't make a lot of sense for code re-use.
Rudy Velthuis [TeamB]
-------------------------
> Ah, this sample, yes. _His_ sample does not need to use interfaces or
> I have misunderstood how he would implement them.
I tend to avoid inheritance as much as possible. One day you'll be
adding a DateOfBirth property to some class and discover that your
Building class somewhere down the tree has a birthday next week :-)
One big benefit of interfaces is that you are only specifying what you
need from another object, the other object is free to descend from
whichever class it likes.
Peter Morris
----------------------------------------
For a good tutorial about the reasons to use interfaces from an OOP
point of view see this chapter of Delphi in a Nutshell by By Ray
Lischner:
http://www.oreilly.com/catalog/delphi/chapter/ch02.html
In particular see this explanation:
Quoting:
"The most important use of interfaces is to separate type inheritance
from class inheritance. Class inheritance is an effective tool for
code reuse. A derived class easily inherits the fields, methods, and
properties of a base class, and thereby avoids reimplementing common
methods. In a strongly typed language, such as Delphi, the compiler
treats a class as a type, and therefore class inheritance becomes
synonymous with type inheritance. In the best of all possible worlds,
though, types and classes are entirely separate.
Textbooks on object-oriented programming often describe an inheritance
relationship as an "is-a" relationship, for example, a TSavingsAccount
"is-a" TAccount. You can see the same idea in Delphi's is operator,
where you test whether an Account variable is TSavingsAccount.
Outside of textbook examples, though, simple is-a relationships break
down. A square is a rectangle, but that doesn't mean you want to
derive TSquare from TRectangle. A rectangle is a polygon, but you
probably don't want to derive TRectangle from TPolygon. Class
inheritance forces a derived class to store all the fields that are
declared in the base class, but in this case, the derived class
doesn't need that information. A TSquare object can get away with
storing a single length for all of its sides. A TRectangle object,
however, must store two lengths. A TPolygon object needs to store many
sides and vertices.
The solution is to separate the type inheritance (a square is a
rectangle is a polygon) from class inheritance (class C inherits the
fields and methods of class B, which inherits the fields and methods
of class A). Use interfaces for type inheritance, so you can leave
class inheritance to do what it does best: inheriting fields and
methods.
In other words, ISquare inherits from IRectangle, which inherits from
IPolygon. The interfaces follow the "is-a" relationship. Entirely
separate from the interfaces, the class TSquare implements ISquare,
IRectangle, and IPolygon. TRectangle implements IRectangle and
IPolygon."
---------------------
For a good example of ref. counting interfaces you can take a look at
the money.pp fpcunit example and the relative tests.
fcl-fpcunit/src/exampletests/money.pp
FPCUnit can be found in the Free Pascal compiler source.
------------ END ---------------------------
Regards,
- Graeme -
_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
More information about the fpc-devel
mailing list