10

Possible Duplicate:
The purpose of interfaces continued

I just started learning Java not so long ago.
I've come across Interfaces which I know how to use but still can't quite grasp the idea of it.
As I understand it, interfaces are usually implemented by classes, which then have to implement the methods declared in the interface.
The problem is - what exactly is the point? Wouldn't it be easier to just implement the methods from the interface as normal class methods? What exactly are the advantages of using interfaces?

I've tried looking for an answer on google. There were many but I still couldn't understand the point of it. I also read this question and its answers, but the whole contract thing just makes it more complicated...

Hopefully someone could simplify it good enough! :)
Thanks in advance!

4

9 に答える 9

12

An interface allows you to provide a different implementation at runtime, inject dependencies, separate concerns, use different implementations for testing.

Just think of an interface as a contract that a class guarantees to implement. The concrete class that implements the interface is irrelevant. Don't know if this helps.

Figured some code might help. This doesn't explain everything there is more to interfaces, keep reading but I hope this gets you started. Point here is that you can vary the implementation...

package stack.overflow.example;

public interface IExampleService {
void callExpensiveService();
}

public class TestService implements IExampleService {

@Override
public void callExpensiveService() {
    // This is a mock service, we run this as many 
    // times as we like for free to test our software

}
}

public class ExpensiveService implements IExampleService {
@Override
public void callExpensiveService() {
    // This performs some really expensive service,
    // Ideally this will only happen in the field
    // We'd rather test as much of our software for
    // free if possible.
}
}


public class Main {

/**
 * @param args
 */
public static void main(String[] args) {

    // In a test program I might write
    IExampleService testService = new TestService();
    testService.callExpensiveService();

    // Alternatively, in a real program I might write
    IExampleService testService = new ExpensiveService();
    testService.callExpensiveService();

    // The difference above, is that we can vary the concrete 
    // class which is instantiated. In reality we can use a 
    // service locator, or use dependency injection to determine 
    // at runtime which class to implement.

    // So in the above example my testing can be done for free, but 
    // real world users would still be charged. Point is that the interface
    // provides a contract that we know will always be fulfilled, regardless 
    // of the implementation. 

}

}
于 2012-12-25T21:15:54.017 に答える
11

Interfaces can be used be used for many things. The most commons uses are polymorphism and dependency injection, where you can change the dependencies at run time. For example, suppose you have an Interface called Database which has one method called getField(...).

public interface Database 
{
    public void getField(String field);
}

Now suppose you have use two databases in your application depending on your client: MySQL and PostgreSQL. You will have two concrete classes:

public class MySQL implements Database
{
    // mysql connection specific code
    @Override
    public void getField(String field)
    {
        // retrieve value from MySQL
    }
}

And...

public class PostgreSQL implements Database
{
    // postgre connection specific code
    @Override
    public String getField(String field)
    {
        // retrieve value from Postgre
    }
}

Now depending on your client preference, you can instantiate a MySQL or PostgreSQL class in your main

 public static void main(String args[])
 {
     if (args[2].equals("mysql"))
         Database db = new MySQL();
     else
         Database db = new PostgreSQL();
 }

 //now get the field
 String foo = db.getField();

Or you can use Factory/Abstract Factory or scripting engine with JS or Ruby.

于 2012-12-25T21:23:03.363 に答える
4

これらは、継承を使用せずにポリモーフィズムを実装するためのものです。

于 2012-12-25T21:11:18.357 に答える
3

The idea with interfaces is that they specify a contract that a class can implement. This idea is largely covered in the other post that you read.

The reason that just implementing the methods from the interface directly isn't enough is that other methods can use the interface type to require that those methods are present.

Let's use AutoCloseable as an example. The only method is a close method, but it's much easier for a method to express the thought "I need a parameter that can be closed" using the type than listing out all of the methods:

public void passMeSomethingThatICanClose(AutoCloseable bar) {
    //stuff goes here
    bar.close(); //the compiler knows this call is possible
}

If we didn't have the concise type name, the method would have to list the requirements explicitly, which wouldn't be very easy, especially when the interface "contract" has many methods.

This works the other way as well. By having a specific keyword "implements AutoCloseable" to signify the intention, the compiler can tell you if you haven't implemented the contract correctly.

public class BrokenCloseable implements AutoCloseable {
    public void colse() {  //ERROR — see the typo?
        //blah
    }    

}

This is an error, because the method has the wrong name. In Java, the compiler can (and will) tell you this. But if you were just responsible for implementing the methods yourself, you wouldn't get an error. Instead, your class would just silently "not be" autocloseable.

Some other languages (Python is a good example) don't do things this way — instead they do things the way you've suggested in the question. This is called "duck typing" (if it looks like a duck, and quacks like a duck, treat it like a duck), and it's also a viable way to do things, just different from Java.

于 2012-12-25T21:23:08.247 に答える
2

インターフェイスは機能を指定します。ある意味で、それらは多重継承を提供します。リストを使って何かをする関数があるとしましょう。しかし、リストだけでなく、あらゆるコレクションです。内容をループできるものなら何でも。だから私はインターフェイスIterableを使用します。

public int randomMethod(Iterable<Integer> li) {
...
}

現在、これはリストとハッシュセット、および実装されて完全に異なる方法で機能し、異なるクラス構造に属するすべての異なるもので機能しますが、すべてがこの基本的な機能を提供します.update()これは、たとえば、インターフェイスを使用することはできますが、共通のクラスを拡張するすべてのエンティティであるビッグゲームループとは異なります。

于 2012-12-25T21:14:21.043 に答える
2

List<T>たとえば、インターフェースを考えてみましょう。特定の機会にまたは(または他の関連するもの)ArrayList<T>を使用するかどうかは、1つのポイントでのみ決定できます。LinkedList<T>

それでも、どちらもList<T>インターフェースを実装しています。したがって、それらがどのように機能するか、またはそれらが階層的に関連しているかどうかに関係なく、使用できる一連のメソッドを公開することが保証され、コレクションオブジェクトの背後にある実装をコードのすべてのポイントで知る必要はありません。で終わる。

于 2012-12-25T21:14:22.550 に答える
2

Because of "The Deadly Diamond of Death". Lets consider this situation:

You write class (name: Parent) in programming language where multiple inheritance is allowed. That class contains one instance variable ( int a;) and one method (void hello()). Then you create two classes (Kid1 and Kid2). Every of that classes extends Parent class. Then you override hello(); method in both Kid1 and Kid2 classes and you assign some value to a variable, also in both Kid1 and Kid2 classes. In last step you create 4th class (like Main) extending Kid1 and Kid2 classes (multiple inheritance). Now...question is, which of hello(); methods will Main class inherit and which value of a variable.

Since there is no multiple inheritance in Java, we have interfaces... abstract classes containing abstract methods. We can implement multiple interfaces, but under condition we have to override all methods which implemented interface contains.

于 2012-12-25T21:21:28.320 に答える
1

ストラテジーパターンとコンポジションパターンを見てみることをお勧めします。

于 2012-12-25T21:15:02.250 に答える
1

あなたの質問は、あまりにも工夫されていたり、有用でなくても一般的すぎたりすることなく、単一の投稿で答える方法です。そこで、インターフェイスが非常に役立つ場合の意味のある例を示します。

Say you have a number of classes which represent various types of objects.. Maybe a dozen, or any sufficiently large number. And you have some function in another class which would like to be able to order arbitrary objects. For that it would need to be able to compare any two objects and determine if one is greater than, or less than another. Since each object could be of any one of your many types of classes this compare function would be pretty tedious to write since it would have to determine what type each object was and then do the comparison by invoking the appropriate logic for each class.

Enter interfaces. At this point, you could just have all your classes implement an interface such as Comparable which specifies that any class implementing it will implement a Compare method.

Now your function that orders object would become trivial to write since it can just rely on the fact that any class of object it needs to compare would have the same Comapre method.

This is just an example - and a rather common one at that.

于 2012-12-25T21:15:40.143 に答える