[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Interfaces, abstract classes. Why?
On Wed, 02 Apr 2003 13:21:25 -0500, Jennifer Fisher was overheard saying:
| Hi all. I hope someone can help me understand better.
|
| What are the uses for interfaces and abstract classes?
| Why would one need them in a project and what for?
The resources the others have provided will expand upon this concept,
but the basic idea behind interfaces is to allow you to define a
number of different "views" of the same object that you can expose to
different consumers of an object. Like objects, interfaces can extend
other interfaces (in fact interfaces can extend more than one
interface, unlike objects which can only extend one object), so you
can chain them together to provide varying levels of access to your
objects depending on who is calling you.
Abstract classes are simply classes that defer the concrete
implementation of a few (or all) methods to a child, and are useful
for situations where you might want to inherit certain behaviors, but
want to force the extending objects to provide their own
implementation of a specific method.
Imagine this simple example: I have a certain object that models part
of my domain. Certain consumers of this object in my application
should only have read access, while others should have read/write. If
we simply pass the object itself anyone can access any of the methods:
we must trust the consumers to call only the appropriate methods (and
trusting an unknown third party is almost always a bad idea).
However, if we define one (or even two) interfaces to our object, we
can limit what operations certain consumers "see." You may sometimes
hear people discuss the use of interfaces as talking "through the
interface," since you can be talking to the same object through may
different interfaces.
The consumer speaking to an interface does not know that more
operations may exist in the object that they're talking to, they are
limited to only the operations that you exposed through the interface.
In this instance we'll have a simple object called a Person. We have
two consumers, an HR application which can view that person's
information, and the Social Security application which can change that
person's name.
Here's the simple ASCII UML diagram (you'll need a fixed width font):
+----------------------------------+
| PersonImpl |
+----------------------------------+
| -name : String |
+----------------------------------+
| +setName(name : String) : void |
| +getName() : String |
| +scream() : void |
+----------------------------------+
| implements
V
+----------------------------------+
| <<interface>> |
| MutablePerson |
+----------------------------------+
| +setName(name : String) : void |
+----------------------------------+
| extends
V
+----------------------------------+
| <<interface>> |
| Person |
+----------------------------------+
| +getName() : String |
+----------------------------------+
If we code HR to "talk to" the Person type (by specifying the Person
type in all of method signatures and return types that will be used by
the HR application), it will not be able to modify our Person's name,
because the setName(String) method exists only in the MutablePerson
interface.
Likewise, we simply code our Social Security application to talk to
the MutablePerson interface, it will be able to get (since
MutablePerson EXTENDS Person) and set the name of the person, however
neither of the consumers will be able to call the scream() method,
because it is not defined in any of the interfaces. Only people who
speak to the object directly (not through an interface) would be able
to invoke the scream() method, even though it is public.
This sort of thing can be abused by explicit downcasting, but it
requires knowledge of the specific underlying implementation of an
interface in order to do so correctly.
-R
--
Robert Gash, gashalot@gashalot.com
(Web) http://gashalot.com/
(PGP) http://gashalot.com/pgpkeys.txt