Use of Java [Interfaces/Abstract Classes]

Use of Java [Interfaces / Abstract classes]

You can think of an interface as a "contract". You are defining a set of methods that classes which implement this interface must implement.

An abstract class, on the other hand, is used when you have some code that could be common to all the child classes you want to implement. So you might have an abstract class called Shape that has some common code, and in your derived classes (Circle, Square, etc.) you could have the code that is specific to those shapes (getArea would be an example). But something like color might be common to all shapes, so you could put a getColor method in your Shape abstract class.

And you can combine the two ideas. You can have abstract classes which implement interfaces, and this gives you the best of both worlds.

These concepts are used over and over again in OO, so it's important to understand them. You seem to be well on your way :).

So if your zombie class has some common behavior that applies to all types of zombies, it sounds like a good candidate to be an abstract class. You could also consider creating an interface (maybe a GameCharacter interface) if you have other characters in your game (maybe UndeadMice or something :)). Then your Zombie abstract class and UndeadMouse abstract class would implement the GameCharacter interface.

How should I have explained the difference between an Interface and an Abstract class?

I will give you an example first:

public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}

Suppose you have 3 databases in your application. Then each and every implementation for that database needs to define the above 2 methods:

public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}

But what if encryptPassword() is not database dependent, and it's the same for each class? Then the above would not be a good approach.

Instead, consider this approach:

public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}

// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}

Now in each child class, we only need to implement one method - the method that is database dependent.

When do I have to use interfaces instead of abstract classes?

From Java How to Program about abstract classes:

Because they’re used only as superclasses in inheritance hierarchies,
we refer to them as abstract superclasses. These classes cannot be
used to instantiate objects, because abstract classes are incomplete.

Subclasses must declare the “missing pieces” to become “concrete” classes,
from which you can instantiate objects. Otherwise, these subclasses, too,
will be abstract.

To answer your question "What is the reason to use interfaces?":

An abstract class’s purpose is to provide an appropriate superclass
from which other classes can inherit and thus share a common design.

As opposed to an interface:

An interface describes a set of methods that can be called on an
object, but does not provide concrete implementations for all the
methods
... Once a class implements an interface, all objects of that class have
an is-a relationship with the interface type, and all objects of the
class are guaranteed to provide the functionality described by the
interface.
This is true of all subclasses of that class as well.

So, to answer your question "I was wondering when I should use interfaces", I think you should use interfaces when you want a full implementation and use abstract classes when you want partial pieces for your design (for reusability)

Why are interfaces preferred to abstract classes?

That interview question reflects a certain belief of the person asking the question. I believe that the person is wrong, and therefore you can go one of two directions.

  1. Give them the answer they want.
  2. Respectfully disagree.

The answer that they want, well, the other posters have highlighted those incredibly well.
Multiple interface inheritance, the inheritance forces the class to make implementation choices, interfaces can be changed easier.

However, if you create a compelling (and correct) argument in your disagreement, then the interviewer might take note.
First, highlight the positive things about interfaces, this is a MUST.
Secondly, I would say that interfaces are better in many scenarios, but they also lead to code duplication which is a negative thing. If you have a wide array of subclasses which will be doing largely the same implementation, plus extra functionality, then you might want an abstract class. It allows you to have many similar objects with fine grained detail, whereas with only interfaces, you must have many distinct objects with almost duplicate code.

Interfaces have many uses, and there is a compelling reason to believe they are 'better'. However you should always be using the correct tool for the job, and that means that you can't write off abstract classes.

When to use an interface instead of an abstract class and vice versa?

I wrote an article about that:

Abstract classes and interfaces

Summarizing:

When we talk about abstract classes we are defining characteristics of an object type; specifying what an object is.

When we talk about an interface and define capabilities that we promise to provide, we are talking about establishing a contract about what the object can do.

what is the advantage of interface over abstract classes?

Interfaces are for when you want to say "I don't care how you do it, but here's what you need to get done."

Abstract classes are for when you want to say "I know what you should do, and I know how you should do it in some/many of the cases."

Abstract classes have some serious drawbacks. For example:

class House {

}

class Boat {

}

class HouseBoat extends /* Uh oh!! */ {
// don't get me started on Farmer's Insurance "Autoboathome" which is also a helicopter
}

You can get through via an interface:

interface Liveable {

}

interface Floatable {

}

class HouseBoat implements Liveable, Floatable {

}

Now, abstract classes are also very useful. For example, consider the AbstractCollection class. It defines the default behavior for very common methods to all Collections, like isEmpty() and contains(Object). You can override these behaviors if you want to, but... is the behavior for determining if a collection is empty really likely to change? Typically it's going to be size == 0. (But it can make a big difference! Sometimes size is expensive to calculate, but determining whether something is empty or not is as easy as looking at the first element.)

And since it won't change often, is it really worth the developer's time to implement that method every... single... time... for every method in that "solved" category? Not to mention when you need to make a change to it, you're going to have code duplication and missed bugs if you had to re-implement it everywhere.

choosing interface or abstract class

Abstract classes are used to group a number of concrete classes under one entity.

For example, take the abstract class Animal.
Animal is not something concrete. it's a family of, well, animals. but they all share certain aspectes, for example, each has a speak() option (well, except fish and sort). but each one implements it differently. this way you can override just the methods which are not the same, for example sleep() or breath() are common (again, fish are differnet :) ).

Interfaces on the other hand are more direct definition of an 'action'. That's why most (if not all) the interfaces in Java ends with 'able' (Comprable, Serializable...)
By implementing the interface, you're telling other programmers or who ever uses your code that this class can do this and this.
A dog, for example, is not, Animable.

Basically, to sum it up, I think that the best definition is this.
Use abstract classes when you have a class that A is kind of B and interface when A can do B.

Hope that's help.

What is the difference between an interface and abstract class?

Interfaces

An interface is a contract: The person writing the interface says, "hey, I accept things looking that way", and the person using the interface says "OK, the class I write looks that way".

An interface is an empty shell. There are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern.

For example (pseudo code):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();

int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

int fuel;

void run()
{
print("Wrroooooooom");
}

int getFuel()
{
return this.fuel;
}
}

Implementing an interface consumes very little CPU, because it's not a class, just a bunch of names, and therefore there isn't any expensive look-up to do. It's great when it matters, such as in embedded devices.


Abstract classes

Abstract classes, unlike interfaces, are classes. They are more expensive to use, because there is a look-up to do when you inherit from them.

Abstract classes look a lot like interfaces, but they have something more: You can define a behavior for them. It's more about a person saying, "these classes should look like that, and they have that in common, so fill in the blanks!".

For example:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

int fuel;

// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}

// That can be very different, force them to provide their
// own implementation.
abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}

Implementation

While abstract classes and interfaces are supposed to be different concepts, the implementations make that statement sometimes untrue. Sometimes, they are not even what you think they are.

In Java, this rule is strongly enforced, while in PHP, interfaces are abstract classes with no method declared.

In Python, abstract classes are more a programming trick you can get from the ABC module and is actually using metaclasses, and therefore classes. And interfaces are more related to duck typing in this language and it's a mix between conventions and special methods that call descriptors (the __method__ methods).

As usual with programming, there is theory, practice, and practice in another language :-)

When to use interface vs abstract class after Java 8

default methods on interface

Apparently you are referring to the feature of “default methods” implementing behavior in an interface.

You should understand that the feature was added as a way around this dilemma: How to retroactively add features leveraging streams and lambda on existing interfaces without breaking existing classes that implement those interfaces?

Many new methods were added to those interfaces such as in the Java Collections Framework. Adding methods to an existing interface would automatically break all classes implementing the interface that are lacking the newly-required methods. Being able to provide a fallback, to give an implementation where one is now required but not yet existing, would resolve the dilemma. Thus « default methods » were born.

To quote from the Oracle tutorial linked above:

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

To quote this Answer by Brian Goetz, Java Language Architect at Oracle:

The proximate reason for adding default methods to interfaces was to support interface evolution

So this feature of adding default behavior to an interface was not meant to be a new mainstream feature in and of itself. The intent of default was not to replace abstract.

Indeed, some experienced Java experts have recommended against making a habit of writing default methods on an interface. They recommend pretty much ignoring that feature of the Java language. Continue to think of interfaces as simply defining a contract, and abstract classes as providing partial implementations meant to be completed in a subclass.

You are certainly free to write your own default methods on your interfaces. And certainly you should do so if you are in a similar situation of having published an interface that others may have implemented, and now you want to add methods. But unnecessarily adding default methods is likely to confuse other programmers who expect partial implementations on an abstract class rather than an interface.

Four situations calling for default method on an interface

In that same post linked above, Brian Goetz suggests three other cases beyond interface evolution where default methods on an interface may be appropriate. Here is a quick mention; see his post for details.

  • Optional methods - The default method throws an UnsupportedOperationException because we expect implementations of this interface to more often not want to implement this method.
  • Convenience methods
  • Combinators

Start with interface, move to abstract class for shared code

As for choosing between an interface and abstract class:

  • Generally start with an interface. Or several interfaces if you want various implementing classes to mix various contracts (see mixin).
    • Think twice before adding a default method. Consider if your situation meets one of the four cases recommended by Brian Goetz as discussed above.
  • If you come to realize that you have duplicated code across multiple classes, then consider centralizing that shared code to an abstract class to be used across subclasses.
    • Alternatively, use composition rather than inheritance (discussed below).

For example, you might have a class for domestic ShippingLabelUS as well as ShippingLabelCanada and ShippingLabelOverseas. All three need to convert between imperial pounds and metric kilograms. You find yourself copying that code between the classes. At this point you might consider having all three classes extend from abstract class ShippingLabel where a single copy of the weight conversion methods live.

While designing your API keep in mind that Java, like most OOP languages, has single-inheritance. So your subclasses are limited to extending only one class. To be a bit more specific about the single-versus-multiple inheritance, I will quote Brian Goetz from this PDF of a slide deck:

[regarding default methods on an interface]

Wait,is this multiple inheritance in Java?

• Java always had multiple inheritance of types

• This adds multiple inheritance of behavior

• But not of state, where most of the trouble comes from

Composition over inheritance

An alternative to using an abstract class for shared behavior is creating a separate class for specific behavior, then adding an object of that separate class to be kept as a member field on the larger class. Wise programmers often share this pearl of wisdom: Prefer composition over inheritance.

Regarding the shipping label example above, you could create a WeightConverter class, an object of which would be a member of each of the three label classes. In this arrangement, no need for the abstract class.



Related Topics



Leave a reply



Submit