问题
I know and understand the value of interfaces in Java. You code to the interface, and then you can change your implementations without having to change any code using the interface. Often the term "contract" is used in connection with interfaces. The way I understand it is the interface defines the "contract" between the application and the implementation.
So, when I create an implementation, I have to fulfill the contract. My questions is, what exactly is in that contract that I have to fulfill?
Obviously, at a minimum you have to provide methods with the same signatures as the interface. The code won't compile otherwise. Is that all the "contract" entails? It seems like there should be more.
For example, I've read articles debating the value of testing to the interface vs. testing specific implementations, or doing both. I see great value in having tests for an interface so that you know what inputs have what expected outputs. It would seem to me that this would also be part of the interface "contract". Every implementation of the interface should produce the same outputs from the same inputs. Obviously there's no way to enforce this contract in the code, but it can be enforced through test cases. Am I wrong in my thinking here?
Finally, what about side effects that implementations have? Here, I'm mainly talking about any persistence that might happen as part of the implementation. Say I have an implementation that is saving some records to the DB while it preforms the operation. Would this somehow be part of the interface "contract"? If so, how could you enforce this contract? From the interface level, I have no idea what the implementation is actually doing. All I know is I give it inputs, and it gives me an output, which I can test. Is any persistence that happens also considered an "output"? If so, I just don't see how this can be tested and enforced. I'm a proponent of persistence ignorance, so I could know that something should be persisted, but I don't know how it is persisted. So, I just don't how to tell when something actually persisted. It may be simple if your interface has some simple CRUD operations, but I want to think about more complicated interfaces.
I hope my question makes sense and that someone can provide some good feedback. I want to discuss this generally, but I can provide a specific example if it's not clear what I'm talking about.
回答1:
I think "contract" and "Interface" have very less in common.
An interface is something like a door. A door may pass typical human, but not elephants, giraffes or car.
An contract is when you could assure that through the door only female, or male, or software developer will come.
So a contract defines BEHAVIOR while interface defines which information is passed
回答2:
I think you're making too big a deal about the term "contract".
"Eiffel" has a very specific "design by contract" philosophy. Personally, I think other languages would benefit from something similar.
Informally, you can certainly think of Java's "interfaces" as being a "contract". Your definition of a Java interface is certainly good:
at a minimum you have to provide methods with the same signatures as the interface. The code won't compile otherwise.
Q: Is that all the "contract" entails?
A: Probably not. It all depends on how you define "contract" ;)
But, IMHO, Java interfaces are a much cleaner feature than the horror of C++ "multiple inheritance". And one of the primary motivations behind both are to support "mixins":
Similarly, Java intefaces also provide a clean, relatively simple, type-save solution to support "callbacks".
Final suggestion: please consider the difference between "interface" and "abstract class". This might also give you additional insight into Java Interfaces, and how you can use them effectively in your own code:
Interface vs Abstract Class (general OO)
回答3:
So a contract is the method signature + any documentation associated with the function / class . A takeaway from this is that an interface does not mean the same thing as the java keyword interface
. An interface is anything that allows you to interact with another system. So to the question of how do you fulfill the contract of a function declared as so:
/** Throws IllegalArgumentException if s is null.
Converts the input <b>s</b> into an {@link Integer} */
function go(String s);
You would need to write an implementation as follows:
function go(String s)
{
if(null == s) throw new IllegalArgumentException();
int i = Integer.parseInt(s);
}
Contrived yes, but this should explain how to implement a contract and abide by it.
来源:https://stackoverflow.com/questions/9948211/java-interfaces-what-exactly-is-in-the-contract