Is there more to an interface than having the correct methods

后端 未结 17 693
小鲜肉
小鲜肉 2020-11-22 13:37

So lets say I have this interface:

public interface IBox
{
   public void setSize(int size);
   public int getSize();
   public int getArea();
  //...and so          


        
相关标签:
17条回答
  • 2020-11-22 14:23

    This is the reason why Factory Patterns and other creational patterns are so popular in Java. You are correct that without them Java doesn't provide an out of the box mechanism for easy abstraction of instantiation. Still, you get abstraction everywhere where you don't create an object in your method, which should be most of your code.

    As an aside, I generally encourage people to not follow the "IRealname" mechanism for naming interfaces. That's a Windows/COM thing that puts one foot in the grave of Hungarian notation and really isn't necessary (Java is already strongly typed, and the whole point of having interfaces is to have them as largely indistinguishable from class types as possible).

    0 讨论(0)
  • 2020-11-22 14:24

    What makes interfaces useful is not the fact that "you can change your mind and use a different implementation later and only have to change the one place where the object is created". That's a non-issue.

    The real point is already in the name: they define an interface that anyone at all can implement to use all code that operates on that interface. The best example is java.util.Collections which provides all kinds of useful methods that operate exclusively on interfaces, such as sort() or reverse() for List. The point here is that this code can now be used to sort or reverse any class that implements the List interfaces - not just ArrayList and LinkedList, but also classes that you write yourself, which may be implemented in a way the people who wrote java.util.Collections never imagined.

    In the same way, you can write code that operates on well-known interfaces, or interfaces you define, and other people can use your code without having to ask you to support their classes.

    Another common use of interfaces is for Callbacks. For example, java.swing.table.TableCellRenderer, which allows you to influence how a Swing table displays the data in a certain column. You implement that interface, pass an instance to the JTable, and at some point during the rendering of the table, your code will get called to do its stuff.

    0 讨论(0)
  • 2020-11-22 14:26

    Don't forget that at a later date you can take an existing class, and make it implement IBox, and it will then become available to all your box-aware code.

    This becomes a bit clearer if interfaces are named -able. e.g.

    public interface Saveable {
    ....
    
    public interface Printable {
    ....
    

    etc. (Naming schemes don't always work e.g. I'm not sure Boxable is appropriate here)

    0 讨论(0)
  • 2020-11-22 14:28

    the only purpose of interfaces is to make sure that the class which implements an interface has got the correct methods in it as described by an interface? Or is there any other use of interfaces?

    I am updating the answer with new features of interface, which have introduced with java 8 version.

    From oracle documentation page on summary of interface :

    An interface declaration can contain

    1. method signatures
    2. default methods
    3. static methods
    4. constant definitions.

    The only methods that have implementations are default and static methods.

    Uses of interface:

    1. To define a contract
    2. To link unrelated classes with has a capabilities (e.g. classes implementing Serializable interface may or may not have any relation between them except implementing that interface
    3. To provide interchangeable implementation e.g. strategy pattern
    4. 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
    5. Organize helper methods in your libraries with static methods ( you can keep static methods specific to an interface in the same interface rather than in a separate class)

    Some related SE questions with respect to difference between abstract class and interface and use cases with working examples:

    What is the difference between an interface and abstract class?

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

    Have a look at documentation page to understand new features added in java 8 : default methods and static methods.

    0 讨论(0)
  • 2020-11-22 14:28

    Here is my understanding of interface advantage. Correct me if I am wrong. Imagine we are developing OS and other team is developing the drivers for some devices. So we have developed an interface StorageDevice. We have two implementations of it (FDD and HDD) provided by other developers team.

    Then we have a OperatingSystem class which can call interface methods such as saveData by just passing an instance of class implemented the StorageDevice interface.

    The advantage here is that we don't care about the implementation of the interface. The other team will do the job by implementing the StorageDevice interface.

    package mypack;
    
    interface StorageDevice {
        void saveData (String data);
    }
    
    
    class FDD implements StorageDevice {
        public void saveData (String data) {
            System.out.println("Save to floppy drive! Data: "+data);
        }
    }
    
    class HDD implements StorageDevice {
        public void saveData (String data) {
            System.out.println("Save to hard disk drive! Data: "+data);
        }
    }
    
    class OperatingSystem {
        public String name;
        StorageDevice[] devices;
        public OperatingSystem(String name, StorageDevice[] devices) {
    
            this.name = name;
            this.devices = devices.clone();
    
            System.out.println("Running OS " + this.name);
            System.out.println("List with storage devices available:");
            for (StorageDevice s: devices) {
                System.out.println(s);
            }
    
        }
    
        public void saveSomeDataToStorageDevice (StorageDevice storage, String data) {
            storage.saveData(data);
        }
    }
    
    public class Main {
    
        public static void main(String[] args) {
    
            StorageDevice fdd0 = new FDD();
            StorageDevice hdd0 = new HDD();     
            StorageDevice[] devs = {fdd0, hdd0};        
            OperatingSystem os = new OperatingSystem("Linux", devs);
            os.saveSomeDataToStorageDevice(fdd0, "blah, blah, blah...");    
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:30

    WHY INTERFACE??????

    It starts with a dog. In particular, a pug.

    The pug has various behaviors:

    public class Pug { 
    private String name;
    public Pug(String n) { name = n; } 
    public String getName() { return name; }  
    public String bark() { return  "Arf!"; } 
    public boolean hasCurlyTail() { return true; } }
    

    And you have a Labrador, who also has a set of behaviors.

    public class Lab { 
    private String name; 
    public Lab(String n) { name = n; } 
    public String getName() { return name; } 
    public String bark() { return "Woof!"; } 
    public boolean hasCurlyTail() { return false; } }
    

    We can make some pugs and labs:

    Pug pug = new Pug("Spot"); 
    Lab lab = new Lab("Fido");
    

    And we can invoke their behaviors:

    pug.bark() -> "Arf!" 
    lab.bark() -> "Woof!" 
    pug.hasCurlyTail() -> true 
    lab.hasCurlyTail() -> false 
    pug.getName() -> "Spot"
    

    Let's say I run a dog kennel and I need to keep track of all the dogs I'm housing. I need to store my pugs and labradors in separate arrays:

    public class Kennel { 
    Pug[] pugs = new Pug[10]; 
    Lab[] labs = new Lab[10];  
    public void addPug(Pug p) { ... } 
    public void addLab(Lab l) { ... } 
    public void printDogs() { // Display names of all the dogs } }
    

    But this is clearly not optimal. If I want to house some poodles, too, I have to change my Kennel definition to add an array of Poodles. In fact, I need a separate array for each kind of dog.

    Insight: both pugs and labradors (and poodles) are types of dogs and they have the same set of behaviors. That is, we can say (for the purposes of this example) that all dogs can bark, have a name, and may or may not have a curly tail. We can use an interface to define what all dogs can do, but leave it up to the specific types of dogs to implement those particular behaviors. The interface says "here are the things that all dogs can do" but doesn't say how each behavior is done.

    public interface Dog 
    {
    public String bark(); 
    public String getName(); 
    public boolean hasCurlyTail(); }
    

    Then I slightly alter the Pug and Lab classes to implement the Dog behaviors. We can say that a Pug is a Dog and a Lab is a dog.

    public class Pug implements Dog {
    // the rest is the same as before } 
    
    public class Lab implements Dog { 
    // the rest is the same as before 
    }
    

    I can still instantiate Pugs and Labs as I previously did, but now I also get a new way to do it:

    Dog d1 = new Pug("Spot"); 
    Dog d2 = new Lab("Fido");
    

    This says that d1 is not only a Dog, it's specifically a Pug. And d2 is also a Dog, specifically a Lab. We can invoke the behaviors and they work as before:

    d1.bark() -> "Arf!" 
    d2.bark() -> "Woof!" 
    d1.hasCurlyTail() -> true 
    d2.hasCurlyTail() -> false 
    d1.getName() -> "Spot"
    

    Here's where all the extra work pays off. The Kennel class become much simpler. I need only one array and one addDog method. Both will work with any object that is a dog; that is, objects that implement the Dog interface.

    public class Kennel {
    Dog[] dogs = new Dog[20]; 
    public void addDog(Dog d) { ... } 
    public void printDogs() {
    // Display names of all the dogs } }
    

    Here's how to use it:

    Kennel k = new Kennel(); 
    Dog d1 = new Pug("Spot"); 
    Dog d2 = new Lab("Fido"); 
    k.addDog(d1); 
    k.addDog(d2); 
    k.printDogs();
    

    The last statement would display: Spot Fido

    An interface give you the ability to specify a set of behaviors that all classes that implement the interface will share in common. Consequently, we can define variables and collections (such as arrays) that don't have to know in advance what kind of specific object they will hold, only that they'll hold objects that implement the interface.

    0 讨论(0)
提交回复
热议问题