开发者

How does the intent of an interface differ from an abstract class with abstract methods?

Explanation/preamble

In Java, if you declare an abstract class with abstract methods, e.g.

public abstract class MyAbstractClass {
  private String m_id;
  
  // default behavior
  public MyAbstractClass() { setId(null); }
  public String getId() { return m_id; }
  public void setId(String id) { m_id = id; }
  
  // overridenable method
  public void doSomething() { /* does nothing by default */ }
  
  // to-be-defined behavior
  public abstract void setSomething(Object o);
  public abstract Object getSomething();
}

you can effectively declare a class which has a "default behavior" of sorts (the getters and setters for m_id) as well as forcing that this class is instantiated by a subclass which has to implement the "missing" (abstract) methods, e.g.

public class MyClass extends MyAbstractClass {
  private Object m_o;
  
  // implements some actual complex behavior
  public void setSomething(Object o) { m_o = o; }
  public Object getSomething() { return m_o; }
}

possibly even overriding methods in the superclass.

So it seems that an abstract class with abstract methods behaves as if it were an interface,

public interface IMy {
  public void setSomething(Object o);
  public Object getSomething();
}

because to use it, it will have to eventually point to an actual object.

The questions

It almost appears as if it makes no sense in existing both interface and abstract class-with-abstract-methods (ACWAM), since they seem very similar.

  1. The ACWAM seems so incredibly similar to an interface! I suppose that the essential difference is in their intent.
  2. I understand that the interface intends to provide a means with which a library user can "talk" to the library without depending on the implementation of the library. Is it a correct interpre开发者_如何学Gotation that an interface is intended to "show something to the public" whereas an ACWAM is something that is intended for the library developer(s) to "agree on", but with the "added bonus" of providing a default (overridenable) behavior?
  3. Would it make sense to use an interface at the same time as an ACWAM?

Can you provide one or two simple examples (pointing to another document would be fine) to illustrate the difference in intent (or "good use") for those two, namely interface and the ACWAM?


The big difference between an interface and an abstract class is:

  • an abstract class imposes a "is a" relationship to the implementation. You must subclass the abstract class. You are forever tied into a particular class hierarchy
  • an interface imposes a "looks like a" relationship to the implementation. You can subclass anything you like as long as it obeys the interface. This frees you up to swap in any class you like to do the job. This is especially useful if a better one comes along

A good rule to work by is that APIs should always refer to interfaces.

Note that the JDK is littered with mistakes made early on where (abstract) classes were used where interfaces should have been used. Stack is a good example: Stack should have been an interface, but it's a class. If you want to implement your own Stack, you must subclass java.util.Stack, which is very prescriptive - you may not want to do that - perhaps you need a super lightweight version etc.

Abstract classes do have their place however: They can provide default implementations of interfaces. A good example is java.util.AbstractMap, a class which is a skeletal implementation of the java.util.Map interface.


Java does not support multiple inheritance. Therefore, a class can implement many interfaces, but it cannot inherit from multiple base classes.


If it helps, you can think of a Java interface as a contract, and a Java abstract class as a template.


Abstarct class is with some/all abstract methods. but Interface is with ALL abstract methods.

In senarios where all the methods are abstarct then go for interface like :

interface City
{
   public void pin();
   public void state();
}

which any city implements will have to provide their own implementation for both the abstract methods.

Ex:

class Bangalore implements City
{
   public void pin()
   {
       System.out.println("127351731");
   }
   public void state()
   {
       System.out.println("Karnataka");
   }
}

class Lisbon implements City
{
   public void pin()
   {
       System.out.println("87456964");
   }
   public void state()
   {
       System.out.println("Lisbon");
   }
}

But lets say for example : in scenarios like this where some methods are common for the classes which extend this class but some they have to give different implementation :

abstract class Animal{
  public abstract void eat();

  public void run()
  {
     System.out.println("I can Run");
  } 

}

And lets say Dog and Cat both extend this abstract class. They both will inherit same run() from the class Animal.

class Dog extends Animal
{
    public void eat()
    {
       System.out.println("I eat Meat");
    }
}

class cat extends Animal
{
    public void eat()
    {
       System.out.println("I eat only Fish");
    }
}


If you have to choose between an interface and an abstract class with ONLY abstract methods, you should choose the interface, since it gives you more possibilities for later : you can have multiple interfaces, but only one abstract class.

If you need some common behavior, you may also choose the interface, since you can have the common behavior via composition in concrete classes (and you benefit of multiple inheritance).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜