Question on abstract classes versus interfaces

M

mdinino

I am brushing up on my Java knowledge for job interviews and I asked
myself a question I couldn't answer:

It seems like it is possible to make an abstract class and an interface
the same. That is, one can define an abstract class with all abstract
methods. In J2SE5 (at least) you can even define variables in
interfaces.

My question, then, is why would anybody ever use an interface as
opposed to abstract classes? Surely there must be some benifit to
using interfaces in some scenarios, I am just not sure what it is.
 
D

Daniel Dyer

I am brushing up on my Java knowledge for job interviews and I asked
myself a question I couldn't answer:

It seems like it is possible to make an abstract class and an interface
the same. That is, one can define an abstract class with all abstract
methods. In J2SE5 (at least) you can even define variables in
interfaces.

My question, then, is why would anybody ever use an interface as
opposed to abstract classes? Surely there must be some benifit to
using interfaces in some scenarios, I am just not sure what it is.

Since Java does not have multiple implementation inheritance, using
abstract classes would be a major limitation. Your class could not extend
another class as well as its 'interface' (i.e. your abstract base class)..
One consequence of this is that a single class could not implement two
'interfaces'. Nor could it derive from any non-'interface' base class.

Dan.
 
S

Suresh Reddi

When you want to create a sub-class extending from two abstract class,
Java wont allow you to do.
But you can impliment as many interfaces as you want to your class.
 
T

Thomas Fritsch

It seems like it is possible to make an abstract class and an interface
the same. That is, one can define an abstract class with all abstract
methods. In J2SE5 (at least) you can even define variables in
interfaces.

My question, then, is why would anybody ever use an interface as
opposed to abstract classes? Surely there must be some benifit to
using interfaces in some scenarios, I am just not sure what it is.
With interfaces you can do:
class A implements Interface1, Interface2 { ...}
But you can't do that with abstract classes:
class A extends AbstractClass1, AbstractClass2 { ...}
 
C

Chris Smith

I am brushing up on my Java knowledge for job interviews and I asked
myself a question I couldn't answer:

It seems like it is possible to make an abstract class and an interface
the same. That is, one can define an abstract class with all abstract
methods. In J2SE5 (at least) you can even define variables in
interfaces.

It appears that for at least part of this, you are confusing a
similarity of syntax with actual similarity. You may define any number
of abstract methods in an abstract class, but you may only define
constants in an interface. Any variable declared in an interface is
implicitly public, static, and final. Ignoring the constants (which are
of historical importance only, and always a bad idea in practice now
that we have static imports instead, even if you believe they were a
good idea beforehand), interfaces do one and only one thing: specify
method signatures that their implementing classes must define.

Why use them? Well, it's certainly cleaner than claiming to inherit
functionality anyway... but the objective reason is that you may
implement any number of interfaces, whereas you may only inherit
functionality from one superclass.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
P

Patricia Shanahan

I am brushing up on my Java knowledge for job interviews and I asked
myself a question I couldn't answer:

It seems like it is possible to make an abstract class and an interface
the same. That is, one can define an abstract class with all abstract
methods. In J2SE5 (at least) you can even define variables in
interfaces.

My question, then, is why would anybody ever use an interface as
opposed to abstract classes? Surely there must be some benifit to
using interfaces in some scenarios, I am just not sure what it is.

In addition to the obvious benefit of being able to implement multiple
interfaces, they seem to me to convey different meanings.

An abstract class always has the possibility of containing
implementation, whether or not it actually does. An interface is only
interface, with no implementation.

Patricia
 
C

Chris Uppal

In J2SE5 (at least) you can even define variables in
interfaces.

Only constants, not variables.

My question, then, is why would anybody ever use an interface as
opposed to abstract classes? Surely there must be some benifit to
using interfaces in some scenarios, I am just not sure what it is.

Here's another view on the topic.

Let's forget about abstract classes for a minute, and consider the difference
between interfaces and concrete classes.

Imagine that you are going to buy a new car. As a potential customer, you
might say:

The car must be red.

(Assuming you like red...). A delivery person might say:

The car is red.

The two sentences are /very/ similar, but they mean /very/ different (but not
unrelated) things. The similarity/difference is closely akin to the
similarity/difference between interfaces and classes. More specifically it is
akin to the difference between what looks like a method (with no body) in an
interface, and an actual method in a class.

In the case of the car you set a requirement which the car sales organisation
has to meet. If the salesthing had said:

The car will be red.

then that would be a promise to you. That pairing of a promise/requirement
forms a contract (probably not one that would stand up in law -- but that's a
different matter). You have made an agreement. Interfaces are the same, they
state conditions on the objects which will be used in certain contexts. If I'm
creating a farm simulation, and you are going to be supplying animals to live
in it, then I might define a contract stating what properties/behaviours your
objects must have before I would allow them as animals on my farm.

// the contract
interface FarmInhabitant
{
void eat();
void sleep();
void shit();
void die();
}

class Farm
{
// before you can use my Farm, you have to sign up to the contract.
// Only objects which act as FarmInhabitants are allowed
addInhabitant(FarmInhabitant it) { ... }
}

As you'll see the contract isn't very expressive -- there's no way I can say
"must not make loud noises all night", "must not tear arms and legs off passing
humans", or "must be tasty and large enough to be worth eating". Some
programming languages attempt to beef up (sorry) the contract language so it
can express more; Java keeps it simple and you are limited to listing the
methods which must be available. Anyway. With that contract defined, you can
create your animals, and pass them to my farm. Your code might follow the
classical OO example:
Cow
IS-A Mammal
IS-A Vertebrate
IS-A Animal
IS-A Eukaryote
IS-A CarbonBasedLifeForm
I (or my farm) just don't care. It's none of my business how you structure
your code. All I care about is that you stick to our contract. In this case
that means that if you want to pass Cows to addInhabitant() then Cow had better
declare that it will meat (sorry) the terms of the contract. I.e. it should
say:
class Cow
extends Mammal
implements FarmInhabitant
{
....
}
And if you do that, the contract even has something like the force of law,
since the compiler won't let you declare that you meet the terms of the
contract unless you actually do (i.e. there are real methods I can call, with
names eat(), sleep(), etc). And if you /do/ meet the terms, then the compiler
won't let me /refuse/ to accept your Cows (I can throw exceptions, but I can't
stop you calling the method in the first place). If someone else wants to use
my farm too, then they might have a completely different set of classes to
create animals (perhaps their Sheep are assembled from a collection of Legs,
Heads, Tails, etc. rather than being a descendant of a deep class hierarchy).
Again, as long as Sheep meet the terms of the FarmInhabitant contract, then
they can be added to my farm. Perhaps even the same farm as your Cows.

Interfaces can also be used the other way around. Not as a requirement, but as
a promise. I can't think of a way to extend the farm example to illustrate
that, but it's probably obvious anyway once you've started to think of
interfaces as contracts.

So an interface defines the contract between the supplier of an object and the
user of that object.

BTW: You can also think of interfaces in a slightly weaker way -- as a way of
/describing/ classes. That brings out the difference between classes and
interfaces rather nicely -- the thing is not the same as the description -- but
since the Java compiler and type system get in on the act, it's probably better
to stick with thinking of interfaces as contracts.

Let's take an aside into "multiple-inheritance". Some people like to say that
Java has multiple inheritance of interfaces. That's technically true, but I
think it misses the point entirely -- and is highly misleading. Going back to
our car example. If I had signed some sort of contract to buy a car, it would
be absurd if I couldn't then buy a house, or take a new job. Yet that's
exactly what would happen if I were only ever allowed to sign one contract. I
can agree to as many contracts as I like (always supposing their terms are
mutually consistent). So why is that like multiple inheritance ? Answer: it
isn't like multiple inheritance at all ! (Yes, it is possible for one
contract to refer to another -- "by agreeing to these terms and conditions, you
also agree to abide by the terms and conditions set out in <such-and-such>" --
and that is much more like inheritance. So there is a sort of inheritance
network between contracts. But that doesn't make it any less absurd to say
that if I have signed two contracts, then I have "multiply inherited" them.)

OK, now we have -- I hope -- a clear picture of the way that interfaces and
classes are totally different kinds of entities, despite their syntactic
similarity. (Recall the syntactic similarity of the two sentences about red
cars). They are not even at the same level -- interfaces are /about/ classes,
rather than being a /variant of/ classes.

So what of abstract classes ? This is where the picture becomes a little
confused, because the Java language design is itself a little confused. The
simple answer is that there shouldn't be any abstract classes in their current
form -- which would completely remove the opportunity for confusion ;-) The
question here is: what do the abstract methods in an abstract class mean ?
What are they for ? And the problem is that, the way Java is designed, there
are two possible answers (depending on the design of the class).

One answer is perfectly legitimate (IMO, although some might disagree). In
this case the abstract class has been designed as a sort of framework or
template, and the abstract methods are there to tell sub-class implementers
what details they are expected to fill in. That is a perfectly reasonable way
of designing frameworks, and abstract methods are a perfectly reasonable way of
expressing that design. It might be better if "abstract" methods were never
public, and could only be called from the superclass, but that's not the way
Java is designed. What we have works well enough in practice (and anyway, we
can always follow the extra restrictions voluntarily even though the compiler
doesn't enforce them).

You'll notice that that use of abstract methods has little in common with the
idea of interfaces as contracts. There is /some/ similarity, but they are
being used much more like the instructions that come in the box with
self-assembly furniture, than like a legal agreement.

Its the other answer which causes problems. Up till this point, we had
complete clarity. Interfaces and classes do different things. Abstract
methods in abstract classes mean something almost entirely unlike the "abstract
methods" in interfaces. But now we get to the place where Java screws up.
Abstract methods can /also/ be used in a sort of interface-y way, as an
explicit promise from a superclass, to users of its subclasses, that those
subclasses will have certain methods, even though it itself doesn't have them.
To my mind, that's just confused. There is no need for the feature since the
superclass could just sign up to the relevant contract (implement the relevant
interface), but not satisfy the terms itself -- thus leaving subclasses to
inherit an obligation which they would have to satisfy. Why the Java designers
choose to muddy the waters like this, I don't know. It may have been intended
to reduce the verbosity of the language, i.e. as an abbreviation for defining
an explicit extra interface and signing up to it. It might be that they were
worried about efficiency. Both those have something to be said for them, but
the gains are small, and the downside is that two concepts which /should/ be
totally, unmistakably, distinct have been muddled together.

There are also some technical limitations of using abstract classes this way
(other people have already described them clearly), but my point is that it
would still be a bad idea even if those limitations were removed, or if didn't
matter in some specific application.

To sum up. Interfaces are for defining contracts. Abstract classes are for
creating frameworks (and the abstract methods should usually be protected).
Abstract classes /can/ also be used to define contracts too, but that's in poor
taste, so we never do it ;-)

-- chris
 
A

alexandre_paterson

Hi Chris,

Chris Uppal wrote:
....
Let's take an aside into "multiple-inheritance". Some people like to say that
Java has multiple inheritance of interfaces. That's technically true, but I
think it misses the point entirely -- and is highly misleading. ....
So why is that like multiple inheritance ? Answer: it
isn't like multiple inheritance at all !

That was a long post!

:)

After reading it, I've got two questions for you:

- if "MI of interfaces" isn't like MI at all, like you're saying,
do you conside single inheritance of interface inheritance at all?


- do you think it is mandatory to rely on concrete inheritance
to achieve OOP ?
 
A

alexandre_paterson

My question, then, is why would anybody ever use an interface as
opposed to abstract classes? Surely there must be some benifit to
using interfaces in some scenarios, I am just not sure what it is.

Depending on your point of view on OOP and on OOP done in Java,
you may as well reverse these questions:

Why would anybody ever use an abstract class as opposed to an
interface? Surely there must be so downsides to using abstract
classes in some scenarios?

Other posters already explained you the differences between
abstract classes and interfaces.

Here's I'll give you just one of the benefits of using interfaces.

You've got to realize that if you inherit from an abstract class,
then you're tied to an implementation. While, for some people
(like me), any implementation should be a detail.

One serious downside of any abstract class that carries
a state is, for example, that it becomes very complicated to
test some part of your application using mock and/or stubs.

That problem is non-existent when programming to an
interface: it is always possible to easily mock/stub objects.

Regarding Java's interface construct, it basically is a "pure
abstract class", that is: an abstract class that carries no
state and no implementation.

Consider this interface:

interface A {
void doIt();
}

and this:

interface A {
abstract doIt();
}

both are perfectly legal and both do exactly the same
(they actually do both compile to the same bytecode).

Note that as I've already said here recently, Java's creator
expressed regrets not having gone "pure interface".

We'd have a simpler language, with two keywords removed
(no more "abstract", no more "protected") and no concrete
inheritance... (see my .sig ;)

I gave you one benefit: easier testing. There are others, like
easier refactoring.

And anything that can be done using an abstract class can
be done using an interface and delegation.

As always, not everything is black or white, this is
Usenet so YMMV.

Talk to you all soon,

Alex
 
C

Chris Uppal

- if "MI of interfaces" isn't like MI at all, like you're saying,
do you conside single inheritance of interface inheritance at all?

I hadn't thought of it before but now you mention it, no I don't. There is
(single) inheritance between Java classes, signified by the keyword 'extends'.
And there is (multiple) inheritance between Java interfaces, also signified by
the keyword 'extends'. But I don't think the relationship between a class and
the interfaces it implements should be called inheritance at all. And,
indeed, it is signified by a different keyword in Java -- so a hearty "Well
done!" to Mr Gosling ;-)

- do you think it is mandatory to rely on concrete inheritance
to achieve OOP ?

Well, it certainly isn't /mandatory/. OO is about objects with polymorphic
behaviour; inheritance (although ubiquitous) is not at all central to OO --
it's hardly even relevant to OO. This is where the notion of interface ==
contract may help. Consider this:

feed(Object animal) // <-- note: "Object"
{
animal.eat();
}

In many languages this would work perfectly well, provided that the objects
passed to feed() did /in fact/ have methods called eat(). So we would have
polymorphic behaviour among all objects which have an eat() method. But what if
one /didn't/ have such a method ? Languages have many ways of dealing with
this; the Java way is for the compiler to try to prove, in advance, that it
can't happen. One way to do that is to set up a promise by the object that it
will have a method called eat():

class Cow
implements FarmInhabitant
{
void eat{) { .... }
}

and a requirement by the user of the object that it must have the method:

feed(FarmInhabitant animal)
{
animal.eat();
}

Now we have a requirement and a promise to satsify it. The compiler checks
that the contract is satisfied, which it is, and so allows the code. There's
no inheritance involved at all.

(There are other ways to express this using words like "type", instead of
"contract", and they are perfectly correct too. But I believe that they tend
to divert attention away from the pure OO concept of polymorphic behaviour. In
particular they tend to produce a confusion between inheritance and
polymorphism.)

It would be perfectly possible to define a completely OO language which didn't
have inheritance (concrete or otherwise) at all. Such a language would have
either a dynamic type system, or a fiendishly complicated static one, but it
could be built, and it would work, and one could do clean OO programming in it.

It would be kind of hard to work with, though. Inheritance is used for two
very important things in real life languages: labour saving and expressing
/necessary/ similarities. My hypothetical language would be terrible at both
(unless it used some innovative scheme for code-sharing without
inheritance[*]).

Switching to the more relevant question of whether one can do OO without
concrete inheritance /in Java/, I would say that roughly the same answer comes
out. It is certainly /possible/ to do clean OO using only interfaces to manage
polymorphism, but in practice it's a right pain in the arse. So, although one
can achieve that level of cleanliness, it's probably better to save it for
"important" places, such as package boundaries, or boundaries between
independent APIs.

-- chris


([*] Delegation-based OO languages, such as Self and ECMAScript, fit this
description.)
 
A

alexandre_paterson

Re Chris,

Chris said:
I hadn't thought of it before but now you mention it,
:)


no, I don't. There is
(single) inheritance between Java classes, signified by the keyword 'extends'.
And there is (multiple) inheritance between Java interfaces, also signified by
the keyword 'extends'. But I don't think the relationship between a class and
the interfaces it implements should be called inheritance at all.

OK, I agree that the relation between a class and the interfaces it
implements isn't "inheritance", but this wasn't exactly what I had
in mind...

When we've got this:

interface A {
... doStuffOne();
... doStuffTwo();
}

interface B extends A {
... doStuffThree();
}

can't we say that interface B is inheriting the contract defined by
interface A ?


And, indeed, it is signified by a different keyword in Java -- so a
hearty "Well done!" to Mr Gosling ;-)

I agree that some keywords are confusing... "final" comes to mind too.

:)

Well, it certainly isn't /mandatory/. OO is about objects with polymorphic
behaviour; inheritance (although ubiquitous) is not at all central to OO --
it's hardly even relevant to OO.

That's exactly what I think: it's hardly relevant to OO.

But /many/ people do think OO == (implementation) inheritance. :(

(There are other ways to express this using words like "type", instead of
"contract", and they are perfectly correct too. But I believe that they tend
to divert attention away from the pure OO concept of polymorphic behaviour. In
particular they tend to produce a confusion between inheritance and
polymorphism.)

I tend to like and use the term ADT ("abstract data type").

It would be kind of hard to work with, though. Inheritance is used for two
very important things in real life languages: labour saving and expressing
/necessary/ similarities.

But for expressing necessary similarities in Java you can use
interfaces:
- two objects implementing the same interface are promising to satisfy
a same contract
- an object implementing an interface promise to satisfy the contract
defined by an interface and hence all the contracts defined by the
"parent interfaces" hierarchy.

I don't see right now how OO could exists without at least that kind
of "specification inheritance" / "contract inheritance" (in Java
"interface A extends B").

Now I'm not sure that's what you meant by "similarities", if you're
talking about code re-use, then (concrete) inheritance may be more
convenient than delegation.


Bjarne Stroustrup said:

"A language or technique is object-oriented if and
"only if it directly supports:
"
"(1) Abstraction - providing some form of classes
" and objects.
"(2) Inheritance -- providing the ability to build new
" abstractions out of existing ones.
"(3) Run-time polymorphism...

Link here: http://www.research.att.com/~bs/oopsla.pdf


This can be done in Java in different ways... What I do is:

1. define my abstract data types using interfaces
2. build new abstract data type based on my
existing interfaces (wether "simple" or "multiple" "extends").
(I'd tend to say this is pretty close to, say, Stroustrup's
definition of "inheritance").
3. sure enough I can see polymorphism at work in
my Java programs (without ever relying on implementation
inheritance).

Now I don't claim to know the one true definition of OO... I just
try to code in an OO'ish way in Java.

Switching to the more relevant question of whether one can do OO without
concrete inheritance /in Java/, I would say that roughly the same answer comes
out. It is certainly /possible/ to do clean OO using only interfaces to manage
polymorphism, but in practice it's a right pain in the arse.

I've seen that said very often but I don't find it too hard to do.
I do (obviously seen that I'm always using interface) rely on
delegation quite a lot. But I don't think it's a problem: my IDE
allows me to delegates all methods to an object in a single shortcut.

Put it in another way: I think the benefits of not using implementation
inheritance (easier testing, easier refactoring, cleaner representation
of my abstract data types, easier documentation [the documentation
lies on the interface, not mixed with code]) outweight the
disadvantages (less convenient to re-use code and hence lots of
delegation everywhere).

As always it's just an opinion and YMMV :)

Talk to you soon on c.l.j.p. and thanks for always taking the time to
discuss these kind of things!

Alex
 
C

Chris Uppal

can't we say that interface B is inheriting the contract defined by
interface A ?

Yes, indeed we can. Or that's what /I/ think (and it seems that everyone else
agrees with me so they must be right ;-)

That's exactly what I think: it's hardly relevant to OO.

But /many/ people do think OO == (implementation) inheritance. :(

I agree.

However, we can console ourselves with the reflection that they are wrong, and
so can be ignored (wherever practical).

I tend to like and use the term ADT ("abstract data type").

I'm not too fond of it myself. I can see the reasoning, but that way of
looking at object puts (IMO) too much emphasis on the /code/ (i.e. the class
represented as source code); rather that on the /objectS/ themselves. E.g. it
does not flaunt the idea that each instance of the ADT has a separate identity
and history. Another example: if you talk of ADTs it's hard to know whether
you are talking about the class or its instances -- the term (IMO) tends to
conflate the two. A last example: I think it's valuable to anthropomorphise
the objects in a program (consider them as if each were a person) as, for
instance, in responsibility-based design. I don't know about you, but I would
find it a lot harder to anthropomorphise an "abstract data type" -- somehow it
doesn't sound much like a person ;-)

I don't see right now how OO could exists without at least that kind
of "specification inheritance" / "contract inheritance" (in Java
"interface A extends B").

I agree. It would probably be impossible. At best it would be insanely
difficult to work with.

Now I'm not sure that's what you meant by "similarities",

I was meaning the case where two classes (or two interfaces, come to that)
/must/ share certain features. One way of expressing that relationship (and a
good way to ensure that the relationship is maintained) is for one class to
inherit that feature from another. (Or for both to inherit it from a third).
In a language with no form of inheritance or delegation, that relationship
would have to be maintained through "cut-and-paste inheritance" (or rather
"cut-and-copy"), which is neither expressive nor easy to maintain.

Bjarne Stroustrup said:

"A language or technique is object-oriented if and
"only if it directly supports:
"
"(1) Abstraction - providing some form of classes
" and objects.
"(2) Inheritance -- providing the ability to build new
" abstractions out of existing ones.
"(3) Run-time polymorphism...

I think he's wrong about (2).


[description of working practice snipped]
Now I don't claim to know the one true definition of OO... I just
try to code in an OO'ish way in Java.

Sounds a reasonable way of working to me -- if it suits you. I think it would
be more work than I care for (except, as I said, at sub-system boundaries), but
see below...

my IDE
allows me to delegates all methods to an object in a single shortcut.

Just an observation: that's getting quite close to defining your own language
layered over Java -- one with a different approach to OO in general. It only
requires one more step -- you do this so often that you instruct your IDE to
generate, or re-generate, these delegation methods automatically (so it does it
every time without having to be told) -- and you will effectively be using
different language. One that is upwardly compatible with, but not the same as,
Java.

Talk to you soon on c.l.j.p. and thanks for always taking the time to
discuss these kind of things!

It's always interesting to discuss how we think about programming.

Cheers.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,585
Members
45,081
Latest member
AnyaMerry

Latest Threads

Top