This week's book giveaway is in the Design forum.
We're giving away four copies of Design for the Mind and have Victor S. Yocco on-line!
See this thread for details.
Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Abstract classes and interfaces

 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all

In a real coding situation, how do we decide when to use abstract classes and when to use interfaces and WHY?


~ Mansukh
 
harshvardhan ojha
Ranch Hand
Posts: 157
1
Android Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mansukh,

Whenever i will have a category i will use abstract class else interface.
Confused?
Lets say i have to declare an interface for a car. By contract every car must have four wheels, its dimensions, color, door.

But what if have to create a contract only for black cars having two doors??

So, as per my understanding if you are having a category for contract, use abstract class, i.e. having implementation for some behavior and contract for some behavior, else Interfaces.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
harshvardhan ojha wrote:Hi Mansukh,

Whenever i will have a category i will use abstract class else interface.
Confused?
Lets say i have to declare an interface for a car. By contract every car must have four wheels, its dimensions, color, door.

But what if have to create a contract only for black cars having two doors??

So, as per my understanding if you are having a category for contract, use abstract class, i.e. having implementation for some behavior and contract for some behavior, else Interfaces.


Hmm.. So what you are saying in essence is that we should try and extend abstract classes in cases where a specialized contract is to be fulfilled. In all other generic cases, we should use interfaces. Correct?
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am trying to break everything down to an interface.
Then i implement some of its methods in an abstract baseclass and later on i implement the fully.
If you have interfaces for most of your classes they are easier to test.
I made it a habbit of mine to always have interface parameter types and never class parameters types whenever possible.
 
harshvardhan ojha
Ranch Hand
Posts: 157
1
Android Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm.. So what you are saying in essence is that we should try and extend abstract classes in cases where a specialized contract is to be fulfilled. In all other generic cases, we should use interfaces. Correct?


To me it seems to be reasonable, but try to use coding practices, prefer interfaces over classes for sake of better design. Hope this was useful.
 
Andy Jack
Ranch Hand
Posts: 257
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interfaces are like a contract which defines behavior or "functions" an implementing class must perform. That is, any class which implements it must define those methods. Java does not support multiple-inheritance because of the problem of "diamond of death". Interfaces were created to avoid problems like those.
I made an example to explain this further - We can think of PogoStick, soccerball, golf ball, racketball-ball implement interface <Bounceable>. It tells the user of implementing classes that these things can bounce. How do they bounce ? Well that depends on the implementing class. Soccer ball might bounce only when airFilled >= 90%, Golf Ball and PogoStick bounce only when contactSurface = "hard". Additionally, pogostick needs a human object to bounce etc.

Abstract classes on the other hand, may define some methods and may declare others. Lets say we define the abstract class Ball.
Ball may or may not (wrecking ball) be bounceable. But, it can certainly roll. Rolling is common to all balls. But deflated soccer ball cannot roll.

Lets define an abstract class -

Ball
{
private String material; // latex, metal, plastic etc. They all have to be made of some substance, right ?
public abstract rolling(int forceApplied); // Golf ball - always rolls. Soccer - checks if airFilled >= 60%. American football - rolls differently and takes more effort to roll.
//I can't think of any other method to define here. Would have made the example better. Maybe getShape(){return shape;} would be suitable.
}

SoccerBall extends Ball implements <Bounceable>
material = leather;

ShotPutBall extends Ball [But does not implement bounceable]
material = steel;

etc


Hope it makes sense. Experienced forum members, please suggest improvements or corrections for my answer. thanks.
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I got a little problem with your kind of Interface usage. Might be a bit picky but I in your case you would "mark" your classes with the interface.
Lets assume you have a list of balls like:

You then have to use an instanceof operator to determine if it is actually bouncable. Which is not exactly clean.

That would even be the case if you declare a method in the interface like:


In your case I would implement it like
 
Andy Jack
Ranch Hand
Posts: 257
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:


I see your point. But, I feel that ShotPut ball should not be forced to implement Bounceable interface because it cannot bounce in our example which considers only hard surfaces. (It could bounce if it falls on jumping board). If someone sees the doc for that ShotPutBall class, he might get confused because they are not supposed to bounce. Makes sense ?
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You may want to have a look at stackoverflow.
I think there are some good answers there.
I wouldn't even create the Bouncable interface for such a type.
Come to think of it I am not a big fan of the idiom "Use interface names with able at the end". This usually leads to overuse of instanceof. You got annotations for that.
 
Jan Hoppmann
Ranch Hand
Posts: 147
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:
Come to think of it I am not a big fan of the idiom "Use interface names with able at the end". This usually leads to overuse of instanceof. You got annotations for that.


But ending your interface name wit 'able' doesn't mean that they are only markers. Look at Runnable, for example. Or Serializable. I end many interfaces in able if the name implies an ability, like being able to be run or serialized.
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Serialisable is a marker interface so i really dont see your point there.
Runnable is one of the interfaces where i am happy with its naming and its funktion.
I am not against using *able for interfaces per se. I am just against using it as an idiom.
 
Jan Hoppmann
Ranch Hand
Posts: 147
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:Serialisable is a marker interface so i really dont see your point there.


But Serializable gives you the opportunity to implement a version number, which in turn is used to determine the class's version, so it does provide functionality and not only marks a class.
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Marking a class with a static number is hardly functional.
 
Jayesh A Lalwani
Rancher
Posts: 2756
32
Eclipse IDE Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bounceable is not a good example here because in real life, everything bounces. Even shot put balls bounce, just not a whole lot. Given a springy enough surface a shot put ball will bounce.

The example I would take is let's say you are building a class hierarchy of vehicles. You have vehicles that drive on land, others that fly, others that swim on the water and others that swim underwater. So, do you make a base abstract class LandVehicle, FlyingVehicle, WaterVehicle and UnderwaterVehicle? If you do, how do you handle vehicles that can fly and go on land, or fly and swim, or amphibious vehicles?


The thing is that you have to think about whether an object IS something, or does it DOES something. It is a very important distinction. A BMW is a vehicle that travels on land. A 747 is a vehicle that flies in the air. An hovercraft is a vehicle that drives on land and water. The ability to driver over land, water or fly is not the essence of their being, but it is something that they do, or are capable of. There's a DOES relationship, not a IS-A relationship.
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:Come to think of it I am not a big fan of the idiom "Use interface names with able at the end". This usually leads to overuse of instanceof. You got annotations for that.

I don't quite see the connection there; although I agree that overuse of marker interfaces can be a bit of a blight.

The only real genuine marker interface that springs to my mind (and I don't include either Cloneable or Serializeable in that list because they have all sorts of "implied" methods and usage) is RandomAccess - no "able" there.

I think it's also true that interface names are often adjectival (and many adjectives end in 'able') because you're describing behaviour, so if class names are nouns, it stands to reason that an interface that groups them together is likely to be an adjective. But it's certainly not a hard-and-fast rule; you should choose the name that best describes what you want.

Winston
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mansukhdeep Thind wrote:In a real coding situation, how do we decide when to use abstract classes and when to use interfaces and WHY?

Personally, I rarely use them without an accompanying interface these days. The interface defines the type, while the abstract class provides a skeleton implementation of the interface, making it easier to create concrete classes.

This paradigm is used quite extensively in the Java collections framework (cf: List/AbstractList, Map/AbstractMap) and I think perhaps that a look at those classes may give you a better idea of how it works than dreamt-up scenarios.

However, a simple example of how useful it can be is this (plagiarised from Effective Java):and there you have it: a fully-functioning List created from an array, which is pretty powerful stuff, considering all the things you can do with a List, including things like ListIterator's that allow you to get items in reverse sequence.

HIH

Winston
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:Serialisable is a marker interface so i really dont see your point there.
Runnable is one of the interfaces where i am happy with its naming and its funktion.
I am not against using *able for interfaces per se. I am just against using it as an idiom.


What is a marker interface Manuel?
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:You may want to have a look at stackoverflow.
I think there are some good answers there.
I wouldn't even create the Bouncable interface for such a type.
Come to think of it I am not a big fan of the idiom "Use interface names with able at the end". This usually leads to overuse of instanceof. You got annotations for that.


Why do you say that using instanceof operator is "not a clean" way to code?
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A marker interface is an interface with no methods.
It is used to mark classes to be able to do something without defining a method to do it. You have to pass the object to another method which then treats the object differently if it implemented this interface.
Serializable and Clonable are such interfaces.
Today you should use annotations if you really need such a case.

instanceof is considered bad by many people because it may indicate that you have code ouside the class which should be inside the class.
You can use the visitor pattern in most of those cases to take the responsibility back to its class.
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mansukhdeep Thind wrote:What is a marker interface Manuel?

An interface with no methods.

A true marker interface generally defines a subtype (as with RandomAccess); but unfortunately, interfaces like Cloneable and Serializable have blurred the distinction somewhat, since they actually define a capability, even though they don't define any methods to support it.

Winston
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:Today you should use annotations if you really need such a case.

Really? Seems a bit like overkill to me.

Could you explain why? It's quite possible that I'm behind the times on this stuff.

Winston
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mansukhdeep Thind wrote:Why do you say that using instanceof operator is "not a clean" way to code?

Because instanceof is generally used as a form of dispatch, which interfaces were designed to avoid (via polymorphism).

As you may have gathered from my question to Manuel, I'm not sure that replacing them with annotations is any better though; and instanecof is extremely fast.

Winston
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:A marker interface is an interface with no methods.
It is used to mark classes to be able to do something without defining a method to do it. You have to pass the object to another method which then treats the object differently if it implemented this interface.
Serializable and Clonable are such interfaces.
Today you should use annotations if you really need such a case.

instanceof is considered bad by many people because it may indicate that you have code ouside the class which should be inside the class.
You can use the visitor pattern in most of those cases to take the responsibility back to its class.


I read that ArrayList class implements RandomAccess marker interface so that I may be able to access the elements in a random manner. Does this mean that internally when we use ArrayList class, we would automatically be ensuring that RandomAccess interface algorithms are being used internally to access the respective elements in an expedited manner? If yes, how does this stuff actually work?
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mansukhdeep Thind wrote:I read that ArrayList class implements RandomAccess marker interface so that I may be able to access the elements in a random manner.

Then you read wrong. If you read the docs again, it says:
"Marker interface used by List implementations to indicate that they support fast (generally constant time) random access."
so it's kind of like a boolean field field that says "yes, I support random access". It just doesn't take up any space.

Does this mean that internally when we use ArrayList class, we would automatically be ensuring that RandomAccess interface algorithms are being used internally to access the respective elements in an expedited manner? If yes, how does this stuff actually work?

No, it means that if you're using a List object, you can find out if it supports random access or not, which might make a difference as to how you do things.

If you already know that your object is an ArrayList, you already know that it implements RandomAccess.

Winston
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If speed is the thing you are going for than instanceof is definitifly your friend i guess but annotations are for metadata which those marker interfaces actually are.
The good thing about annotations is that they are not inherited like interfaces.
Sometimes its not a good idea to have your whole inheritance tree serialisable just because one parent is.
Maybe marker interfaces still have their place in rare conditions.
The only good examples to use instanceof might be in the equals method or if you are using a library which classes you cannot extend because they are final or something like that.
 
Winston Gutkowski
Bartender
Pie
Posts: 10243
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:If speed is the thing you are going for than instanceof is definitifly your friend i guess but annotations are for metadata which those marker interfaces actually are.
The good thing about annotations is that they are not inherited like interfaces.

In which case, surely we're just talking about dispatch code and debating about which form to use.

Personally, I hate dispatch code in any form, because it smacks to me of laziness; but in a few (and I do agree that it's very few) cases I reckon a marker interface is acceptable. Indeed, I think that it might have been better if RuntimeException had been made one, instead of a fully-fledged subtype.

But Annotations? Unless there's a possibility of adding flexibility via dependency injection, I don't honestly see how it helps.

But, as I say, maybe it's just me being thick here.

Winston
 
Ivan Jozsef Balazs
Rancher
Posts: 972
5
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:Please correct my english.


... my English.
 
Manuel Petermann
Ranch Hand
Posts: 177
Hibernate Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for that one.
 
Ivan Jozsef Balazs
Rancher
Posts: 972
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manuel Petermann wrote:Thanks for that one.


Es freut mich geholfen zu haben ;-)
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic