Thursday, April 14, 2011

What is the purpose of interfaces?

I want to understand the purpose of interfaces. I know how to declare an interface and how to implement the interface, but what is the need of it? I need to understand the reason for using interfaces. In every programming course, the teacher has said, "It is a contract. It has just definitions of methods and properties," and given an example like this:

interface I {
  public int sum(int a, int b);
}

class C implements I {
 public int sum(int a , int b ){
  return a+b;
 }
}

OR

interface I {
  public int sum(int a, int b);
}

class C:I  {
 public int sum(int a , int b ){
  return a+b;
 }
}

This tells me how to use the interface. If I implement the interface I have to write the function.

But why should I do this? What are the problems that interfaces address?

From stackoverflow
  • Are you happy with the idea of inheritance and abstract classes? For example, do you see why it's nice to have a Stream class (or InputStream/OutputStream in Java) which anyone who wants to read/write data can use and not have to know whether they're writing to a file, memory, the network, or whatever?

    Well interfaces are just like that, but they don't force you to use a particular base class. That's important in .NET and Java, where a class can't have multiple base classes, but can implement multiple interfaces. It means that a class can implement IDisposable and IEnumerable<string> for example - which wouldn't be possible if they were abstract base classes.

    Jon Skeet : Downvoters: a downvote without a comment isn't particularly useful. Please explain your reason for downvoting.
    Amir Afghani : I just read this answer and it's convinced me that yes, indeed, Jon Skeet deserves his 161k rep.
  • -- EDIT --

    After some comments on other answers, I thought I'd expound on this a bit.

    Interfaces provide the means to say my class can behave as an XXXX or you can treat my object as an XXX. So, for example, when you say:

    class FileLogger : ILogger // Interface
    

    You are in effect saying "You can treat my class as if it were an "ILogger".

    If the class IS a specific type of object, using a base class and hierarchy is a better approach. In that case, I'd say:

    class FileLogger : Logger // Abstract or Concrete base class
    

    In this case, you are saying FileLogger IS A logger. In addition, this allows you to do:

    class FileLogger : Logger, IDisposable
    

    Which suggests that FileLogger IS A logger but also acts as an (or implements the functionality to work as an) IDisposable. The two concepts are different, and both useful.

    -- ORIGINAL --

    Interfaces provide another level of abstraction. They allow an object to be reused flexibly, but the implementation to be restricted to the object.

    This has many uses, especially in languages like C# and Java where you have single inheritance. Interfaces allow an object to be used more flexibly in cases like this, and simulate most of the advantages of multiple inheritance while avoiding the main problems with multiple inheritance.


    For example, in C#, there is a common interface called IDisposable. This interface states that any object implementing it contains native resources that should be "disposed" of and cleaned up. This can work for any type of object.

    If an abstract base class was used for this purpose, any object containing native resources would have to derive from that base class, and not potentially some other base class that makes more sense. Interfaces provide the ability for any object, in any hierarchy, to say "I have native resources, so clean me up when you're done using me." The even provide the language itself a way to handle this (via the using statement).

    Without this, say you had a FileLogger, and it subclassed a Logger class. The default "Logger" class may just log to the screen - it doesn't have any native resources, so it wouldn't need to be cleaned up. Because of this, it wouldn't have derived from the (theoretical) "Disposable" base class.

    Now, you want to add a FileLogger. This is a Logger, so you'd want to subclass Logger. But here you'd be in trouble - since your Logger now contains native resources internally (the file handle), you'd want to be able to also subclass "Disposable", but you can't do that.

    With interfaces, you're free to subclass ONE class, but also implement any number of interfaces. This issue doesn't happen.

    eglasius : I don't think using "acts as a" are enough arguments. For that matter I think they are more a "behaves like an" ILogger. That also makes more sense for: behaves as an IDisposable. I make a clear case for the interface in my own answer. I also don't agree with the abstract is less coupled comment.
    Reed Copsey : "Acts as" is the term a lot of books use. "Behaves like" to me suggests the same thing. My main argument is that inheritance should be used if the base class "is a specific type of" the base class.
  • The main reason to use interfaces is when you want to be able to have several classes that can be substituted for one another, but have completely different implementations.

    For example, in Java's collections, I can have...

    java.util.Map<Integer, String> myMap;
    myMap = new java.util.HashMap<Integer, String>(); // Unsorted
    myMap = new java.util.TreeMap<Integer, String>(); // Sorted
    myMap = new java.util.concurrent.ConcurrentHashMap<Integer, String>(); // Unsorted, but writes are synchronized
    

    All 3 of those are implemented differently, but since they are all implementations of Map<Integer, String>, I can set myMap to any of these and still call

    myMap.put(1, "A String");
    String myString = myMap.get(1); // myString will be "A String"
    

    The other thing is that you can only call methods on them common to the Map class. This is important, as TreeMap is actually a SortedMap, while ConcurrentHashMap is actually a ConcurrentMap. SortedMap and ConcurrentMap inherit from Map, but methods specific to those interfaces are not available if they are declared as a Map.

    Likewise, in .NET, you'll be bitten if you declare something as an IList<K, V> and then try to call .Sort() on it, as .Sort() is part of List<K, V> but not IList<K, V>.

    R. Bemrose : This is an old, old, old answer by now, but there is one thing I never addressed: The only reason to have a `SortedMap` in Java is if you need to iterate over it. `SortedMap`s like `TreeMap` have a guaranteed order, the others don't.
  • The real purpose of an interface is if you want more than one concrete class to inherit from it. An instance of a class C that inherits from an interface I can be cast to an instance of I just as if I were a class. This allows something like:

    interface I {
        // Stuff.
    }
    
    class C1 : I {
        // Stuff.
    }
    
    class C2 : I {
        // Stuff.
    }
    
    void useAnI(I myInterface) {  
        // Call functions defined in I.
    }
    

    At a lower level, the reason for interfaces existing and requiring that the contracts be spelled out explicitly is to tell the compiler/VM how to lay out the virtual function table. The other way to solve this problem is duck typing (like Python or Ruby), in which the names are actually used at runtime to call the functions. The main downsides are that it is slower than virtual function tables and explicit interfaces and that it arguably makes maintenance harder because contracts are less explicit.

    Without one of these two mechanisms, the program would have no idea which concrete implementation of a function to call. For example, if I defines a funciton foo(), and C1 and C2 both implement foo(), when you call useAnI(someC1), it will use C1.foo(), and when you call useAnI(someC2), it will use C2.foo().

  • Here is a C# example:

    interface ILogger
    {
        void Log();
    }
    
    class FileLogger : ILogger
    {
        public void Log() { }
    }
    
    class DataBaseLogger : ILogger
    {
        public void Log() { }
    }
    

    I have an ILogger interface with one Log method. I am now free to use the ILogger interface throughout my code and never worry about how things get logged - I just want to log them. This means that in the future if I want to switch from using a FileLogger to a DatabaseLogger I can do so with minimum inpact.

    Martin : Nice exemple, but would be more useful with a bit more code.
    Reed Copsey : This could be done with an abstract base class, as well, in this example. I don't think it really highlights the unique advantages of interfaces.
    Martin : when you can use an interface, use an interface, inheritance can cause much more maintenace troubles than an interface. Also, in many language, you don't have multiple inheritance, but you can implement as many interfaces as you like.
    eglasius : +1 simple examples :) - added a related scenario on my answer
    Mr. Shiny and New : @Reed Copsey: An abstract base class IS an interface. An Interface is an abstract base class with only abstract methods. The only difference is whether your language of choice allows multiple inheritance. Conceptually they are otherwise pretty much equivalent.
    OscarRyz : I think some OO theory is in order. I'll write about that
    Reed Copsey : Martin and Mr. Shiny and New: In .NET, the Framework Design Guidelines 2nd Edition say the opposite. Specifically: "Do use abstract classes instead of interfaces to decouple the contract from implementations." - Cwalina and Abrams
    Reed Copsey : Interfaces are conceptually different than abstract base classes. Abstract base classes should define an "Is-A" relationship - interfaces define a "Acts-Like" relationship. I'll modify my answer to expound on this.
  • Andrew's response - modified a bit

    interface ILogger
    {
        void Log(string message);
    }
    
    class FileLogger : ILogger
    {
        public void Log(string message) { }
    }
    
    class DataBaseLogger : ILogger
    {
        public void Log(string message) { }
    }
    

    Expending on Andrew Hare's answer:

    class LogManager 
    {
       ... Define constructor and various things ...
    
        private ILogger logger;
    
        public void setLogger(ILogger logger)
        {
            this.logger = logger;
        }
    
        public void Log(string message)
        {
            this.logger.log(message)
        }
    
    }
    

    Using interface here avoids the LogManager being tied to anyclass. The design is therefore extensible, because you could create any class, implement the interface, and use it with the LogManager.

    If you want to see a lot more examples of where to use interfaces, you should take a look at the book : Head First Design Patterns

  • Interfaces don't make since in a situation where you're only going to try something one way. You can think of interface implementing classes as contractors who offer you bids to get the job. You might seek the contractor that offers you the shortest run time, the least memory, or the most extra features.

    public IContract
    {
        string Action(string[] strings);
    }
    
    public SimpleContractor : IContract
    {
        public string Action(string[] strings)
        {
            string result = string.Empty;
            for (int i = 0; i < strings.Length; i++)
            {
                result += strings[i];
            }
    
            return result;
        }
    }
    
    public StringBuilderContractor : IContract
    {
        public string Action(string[] strings)
        {
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < strings.Length; i++)
            {
                result.Append(strings[i]);
            }
    
            return result.ToString();
        }
    }
    
    public BonusFeatureContractor : IContract
    {
        string result = null;
    
        public string Action(string[] strings)
        {
            if (result == null)
            {
                string result = string.Empty;
                for (int i = 0; i < strings.Length; i++)
                {
                    result += strings[i];
                }
            }
            return result;
        }
    }
    

    A good example of this is serialization. You can serialize data into memory, text, binary, XML, etc. All the serializers use the same interface, so you can literally go from XML to Binary by changing your instance. The code itself won't need to change.

  • If you only have a single implementing class, then an interface is almost entirely pointless (there are some oddities where it may be useful, such as dynamic loading).

    If you have polymorphism - different class implementations that you want some client code to treat exactly the same - then interfaces should be your first choice (fully abstract classes will also work but are less clear).

    Martin : You might have more than one in the future. Using interfaces from the start, might make your code more futureproof, but it might also complexify your design. A good balance should be used, but I would not say it is almost entirely pointless.
    Tom Hawtin - tackline : Really, if you have both interface and class to maintain you are killing yourself. Keeping the docs away from the code - exact opposite of what makes JavaDoc great. When you do need a separate implementation all you need to change in the client is the new. ...
    Tom Hawtin - tackline : ... Generating the interface is also easy (as opposed to maintaining it). If you didn't anticipate needing multiple implementations, almost certainly you wont be able to anticipate a reasonable interface either.
  • Consider you have andrew's example in place, and you later need to use a logger that forced you to use a specific base class (and you don't have control of that). You can do that just like:

    public class MySpecialLogger : SpecialLoggerBase, ILogger
    {
        public void Log() { }
    }
    

    If you would have gone with a Logger base class, then you would be tie to it and would need more code to overcome that. It might not be the best example, it explains the point.

    Andrew Hare : +1 Nice addition, thanks!
    eglasius : @Andrew feel free to add the scenario to your answer :)
    eglasius : @Andrew added the combined answer to the related question http://stackoverflow.com/questions/444245/how-will-i-know-when-to-create-an-interface/667457#667457 --- this one looks on its way to be closed as a dupe :(
  • It's basically used to tell some other piece of code "I want you to do the job for me and return only the result - I don't case how you do it".

    If you only call your class through the interface it implements, then you are sure that you can replace it with a different class at any moment (providing that a different class also implements the interface).

  • One thing that I don't see mentioned with interfaces v inheritance is that the implementing class can implement multiple interfaces but it cant inherit from multiple classes.

    This can make your class design easier to understand and to follow more contracts.

    as

    interface I {
          public int sum(int a, int b);
        }
       interface B {
           public int subtract(int a, int b);
       }
        //quite happy to do
       class C : I, B {
           public int sum(int a, int b) {
               return a + b;
           }
           public int subtract(int a, int b) {
               return a - b;
           }
       }
    
    
       public class Addition {
           public Addition() { }
           public int Add(int a, int b) {
               return a + b;
           }
       }
       public class Subtract {
           public Subtract() { }
           public int Sub(int a, int b) {
               return a - b;
           }
       }
        //cannot do!
       public class Math : Addition, Subtract {
    
       }
    
  • This is going to be sort of general sounding, but in one of my projects we have a couple of different ways of generating data for a simulation study. So, we might have dA.results, and dB.results which are similar in form, but not exactly the same. We pass them to our "interface" class, and regardless of the type of data, the interface produces a common object.

    Now, we have multiple classes that compute statistics on that data. (sA, sB, sC, etc.)

    (simple, right? we have data and statistics that operate on that data)

    We want to compare the results from each of those statistics, so we always want to be passing the same object into each statistic.

    so the flow would look like

    //generate data
    dA.generate();
    db.generate();
    
    //pass to interface
    I1 = dataToStatInterface(dA.results());
    I2 = dataToStatInterface(db.results());
    
    //compute statistics using common interface
    sA(I1);
    SA(I2);
    sB(I1);
    sB(I2);
    

    Here's a big reason why this is good:

    We're always getting the same object to construct from.

    This makes life simple. Now, if we add a new data type, we don't need to write a new constructor for every existing statistic (we just add a new interface subclass). AND, if we create a new statistic, we don't need to write a new constructor for every data type (we just need the constructor for the object that comes from the interface).

    Just to confuse matters. . .

    "interface" is also used in a different sense, and that's how a lot of your answerers are using it. In this same project, each statistic derives from a base statistic which provides a common interface. This is typical inheritance. For any statistic, we know we can call

    sA.printResults(); sB.printResults();

    That's an interface, too, and it does mean the same thing as my interface class, but it is a slightly different notion.

  • The answers to this question will give you some insight:

    http://stackoverflow.com/questions/444245

  • -First some OO theory:

    In OO paradigm in general, the interface or the public interface is constituted by the methods an object has.

    The interface answer to the question: what operations may be performed by this object?

    That's why is often explained as the "contract".

    Object "a" of class "Xyz" should do:

    // one operation that doesn't return anything
    -oneOperation():void 
    
    // other operation that return boolean
    -otherOperation():bool   
    
    // another that receives two string and return a String 
    -anotherOperation( a: String, b String ): String  
    
    
    
    etc. etc.
    

    It may additionally perform other operations inside the class, private operations, that's the object private interface, we don't care too much about that because, well, we can't use it since it's private ( we do care if we are modifying the class source code, but's that's another topic)

    That's about OO theory very high level.

    -Implementations

    In programming languages such as Java and C# which are statically typed the operations of an object are defined by the type that object belongs to AT COMPILE TIME ( this is important )

    For instance, in Java the object

    "Oscar"
    

    Has a method

    // Returns the character at specified index 
    -charAt( index: int ) : char
    

    We know this, because that objects is of type String and the public interface of String defines the charAt method.

    So, the compilers check that a method named "charAt" does exists in that object ( and help you with typing mistakes such as chatAt )

    -So, back to your question

    So, after all this explanation and returning to your original question:

    but what is the need of it?

    When you're defining a system using OO technology and specifically using an statically typed programming language such as Java and C# you define the operations your object will respond.

    As we see before, that will be implicity defined by the type of the object; the class that is. But, ¿what happens, when you need that two objects from different class hierarchies respond to the same operation?

    What C++ did, was to allow multiple inheritance, an object may inherit the public interface of two different classes, such as "Bird" and "Horse" creating a "Pegasus" class.

    The problem with inheritance is that's the worst form of high-coupling which is not desirable ( nor avoidable though ) and C++ multiple inheritance presented some additional problems it self.

    So when Java was designed ( and C# in consequence, since this was a good feature ) they forbid multiple inheritance and as a workaround they introduced the interface keyword, to allow you to work on the situation when you need two classes from different type hierarchy respond to the same method.

    In both, the way the interface will work, is only to define what operations the object will respond to ( exactly as the OO concept ) and thus all of them should be public.

    When a class is said to implement and interface, it commits to have those methods available.

    A very easy to understand usage of and interface is Comparable which allows to the implementers to compare against another object.

    For instance it may be simple to decide which object should go first when sorting a collections of numbers, 1 will be lower than 10,

    But, if you have a collection of employees? Which should go first?, bye age?, by role? by name? This should be defined by the need of the system

    Yet, you can create a data structure to hold for multiple kinds of objects granted that all of them respond to the :

    -compareTo(o: T ): int
    

    method.

    And of course not all of them should inherit the same class.

    I hope this helps.

  • Points to remember

    • A Interface defines how two objects interact with each other.
    • Interfaces are used when two object need to interact independently of their implementation. For example a Network Stack.All the application cares about that it is dealing with a network. Not whether it is Ethernet, or Token Ring.
    • A Interface is implemented by a class.
    • A variable defined as the Interface can have any objects implementing that interface assigned to it.
    • Some languages, like C++, do not clearly distinguish between the interface of a class and it's implementation. Causes confusion to people moving to languages that do make distinction.
    • Most object oriented languages use the public members of a class as the default interface for convenience.

    Section 1.6 starting on page 11 of Design Patterns has a excellent summary on the topic.

  • Callbacks are another example of using interfaces. Say you have a third party class with a method that opens PDF files and extracts data from them. PDF files can have password protection with encryption. So that method may need a password. It can be declared as taking an interface pointer:

    void DoStuff( string filename, IPasswordCallback callback );
    

    where the callback interface is

    interface IPasswordCallback {
        virtual string GetPassword();
    };
    

    Now you can have any implementation of this interface - you just inherit from it and implement the method. It can read password from .ini file, ask user, call the operator, return one password from a set of passwords in some database, return some predefined string or whatever. The consuming method (DoStuff()) doesn't care. It only knows that it can retrieve a password via this interface.

  • There are a number of different ways to describe the relationship of one class to another. A common way is "is-a" (inheritance) and "has-a" (membership). Interface is another "acts-like-a", which is a great way to attach behaviors onto a class.

0 comments:

Post a Comment