Java doesn't allow the multiple inheritance to protect diamond problem. It uses interface to take care of this problem.
Then the case of using interface, let's say
interface A{
run();
}
interface B{
run();
}
class C implements A, B{
run() {} //Which interface we are using?
}
When we call the method run() in the class C, how can we determine which interface we are using?
You don´t. And it does not matter, since the implementation is not on the interface but on the class. So the implementation is unique. No ambiguity.
What does matter is if each declaration wants to have a different return type:
interface A{
void run();
}
interface B{
String run();
}
class C implements A, B{
???? run() {}
}
This is the only way you can have problems with multiple interfaces in Java.
It does not matter. The purpose of the interface is to indicate that the class C has a method run(). You can depend on that method being there.
Even though both A and B specify the run method it is only implemented once so there is no conflict.
When you say you are using an interface it really means how your objects are declared:
A myobject = new C();
myobject.run();
vs
B myObject = new C();
myobject.run();
In the first case you are "using" the A interface, that is, your code is assuming that the myobject Object is of type A and that it has a method called run(). In the second case you are "using" the interface B.
If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics.
Compatibility example
Here's an example where you have an interface Gift, which has a present() method (as in, presenting gifts), and also an interface Guest, which also has a present() method (as in, the guest is present and not absent).
Presentable johnny is both a Gift and a Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
#Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
The above snippet compiles and runs.
Note that there is only one #Override necessary!!!. This is because Gift.present() and Guest.present() are "#Override-equivalent" (JLS 8.4.2).
Thus, johnny only has one implementation of present(), and it doesn't matter how you treat johnny, whether as a Gift or as a Guest, there is only one method to invoke.
Incompatibility example
Here's an example where the two inherited methods are NOT #Override-equivalent:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
This further reiterates that inheriting members from an interface must obey the general rule of member declarations. Here we have Gift and Guest define present() with incompatible return types: one void the other boolean. For the same reason that you can't an void present() and a boolean present() in one type, this example results in a compilation error.
Summary
You can inherit methods that are #Override-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE #Override-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.
The compiler does not have to identify which method is for which interface, because once they are determined to be #Override-equivalent, they're the same method.
Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.
References
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.8.4
Even if you implement multiple interfaces with same method declarations, you will only have one definition of that method in your class. So, there isn't any ambiguity here since there is only one method to call.
You can't tell; however it doesn't matter either, as interfaces have no functionality.
This will change slightly when Java 8 comes out as then interfaces can have default implementations of functions; if there's more than one default implementation then there might be ambiquity. How this is solved is explained in the question Are defaults in JDK 8 a form of multiple inheritance in Java?.
Your question doesn't make much sense. Let's take a realistic example. A Human can cry. An AnimalBaby can cry. Now you have an instance John which is both a Human and an AnimalBaby, and you make it cry. What happens? John cries. The fact that it implements the cry() methods of both interfaces doesn't change what crying means and does for John.
Both. C inherited two methods from two interfaces (which happen to be override-equivalent (8.4.8.4)). C then have one method that overrides both because the signature matches both. (8.4.2)
However, one could wonder - just because two methods have the same name and parameter types, does not necessarily mean they have the same semantics. The name could very well be one english word that means two different things. What if we inherited two methods from two super interfaces that look the same but are actually different in semantics, therefore there should be two implementations in the subclass? For example
interface java.lang.Runnable
void run()
interface com.animal.Runnable
void run()
class Dog implements com.animal.Runnable,
java.lang.Runnable // a dog as a task
???
We can imagine a language that can handle such cases. But Java does not do that. If two methods are similar enough, they are assumed to have the same semantics. Fortunately in practice this does seems to be a problem anyway.
Related
I am not asking this -> Why is there no multiple inheritance in Java, but implementing multiple interfaces is allowed?
In Java, multiple inheritance isn't allowed, but, after Java 8, Interfaces can have default methods (can implement methods itself), just like abstract classes. Within this context, it multiple inheritance should also be allowed.
interface TestInterface
{
// abstract method
public void square(int a);
// default method
default void show()
{
System.out.println("Default Method Executed");
}
}
Things are not so simple.
If a class implements multiple interfaces that defines default methods with the same signature the compiler will force you to override this method for the class.
For example with these two interfaces :
public interface Foo {
default void doThat() {
// ...
}
}
public interface Bar {
default void doThat() {
// ...
}
}
It will not compile :
public class FooBar implements Foo, Bar{
}
You should define/override the method to remove the ambiguity.
You could for example delegate to the Bar implementation such as :
public class FooBar implements Foo, Bar{
#Override
public void doThat() {
Bar.super.doThat();
}
}
or delegate to the Foo implementation such as : :
public class FooBar implements Foo, Bar {
#Override
public void doThat() {
Foo.super.doThat();
}
}
or still define another behavior :
public class FooBar implements Foo, Bar {
#Override
public void doThat() {
// ...
}
}
That constraint shows that Java doesn't allow multiple inheritancy even for interface default methods.
I think that we cannot apply the same logic for multiple inheritances because multiples issues could occur which the main are :
overriding/removing the ambiguity for a method in both inherited classes could introduce side effects and change the overall behavior of the inherited classes if they rely on this method internally. With default interfaces this risk is also around but it should be much less rare since default methods are not designed to introduce complex processings such as multiple internal invocations inside the class or to be stateful (indeed interfaces cannot host instance field).
how to inherit multiple fields ? And even if the language allowed it you would have exactly the same issue as this previously quoted : side effect in the behavior of the inherited class : a int foo field defined in a A and B class that you want to subclass doesn't have the same meaning and intention.
The language designers already thought about that, so these things are enforced by the compiler. So if you define:
interface First {
default void go() {
}
}
interface Second {
default void go() {
}
}
And you implement a class for both interfaces:
static class Impl implements First, Second {
}
you will get a compilation error; and you would need to override go to not create the ambiguity around it.
But you could be thinking that you can trick the compiler here, by doing:
interface First {
public default void go() {
}
}
static abstract class Second {
abstract void go();
}
static class Impl extends Second implements First {
}
You could think that First::go already provides an implementation for Second::go and it should be fine. This is too taken care of, thus this does not compile either.
JLS 9.4.1.3 : Similarly, when an abstract and a default method with matching signatures are inherited, we produce an error. In this case, it would be possible to give priority to one or the other - perhaps we would assume that the default method provides a reasonable implementation for the abstract method, too. But this is risky, since other than the coincidental name and signature, we have no reason to believe that the default method behaves consistently with the abstract method's contract - the default method may not have even existed when the subinterface was originally developed. It is safer in this situation to ask the user to actively assert that the default implementation is appropriate (via an overriding declaration).
The last point I would bring in, to solidify that multiple inheritance is not allowed even with new additions in java, is that static methods from interfaces are not inherited. static methods are inherited by default:
static class Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre extends Bug {
static void test() {
printIt(); // this will work just fine
}
}
But if we change that for an interface (and you can implement multiple interfaces, unlike classes):
interface Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre implements Bug {
static void test() {
printIt(); // this will not compile
}
}
Now, this is prohibited by the compiler and JLS too:
JLS 8.4.8 : A class does not inherit static methods from its superinterfaces.
Java doesn't allow multiple inheritance for fields. This would be difficult to support in the JVM as you can only have references to the start of an object where the header is, not arbitrary memory locations.
In Oracle/Openjdk, objects have a header followed by the fields of the most super class, then the next most super class, etc. It would be a significant change to allow the fields of a class to appear at different offsets relative to the header of an object for different subclasses. Most likely object references would have to become a reference to the object header and a reference to the fields to support this.
default methods in interfaces pose a problem that :
If both of the implemented interfaces define a default method with
same method signature, then the implementation class does not know
which default method to use.
The implementation class should define explicitly specify which default method to use or define it's own one.
Thus default methods in Java-8 do not facilitate multiple inheritance. The main motivation behind default methods is that if at some point we need to add a method to an existing interface, we can add a method without changing the existing implementation classes. In this way, the interface is still compatible with older versions. However, we should remember the motivation of using Default Methods and should keep the separation of interface and implementation.
The main issues with multiple inheritance are ordering (for overriding and calls to super), fields and constructors; interfaces don't have fields or constructors, so they don't cause problems.
If you look at other languages they usually fall in two broad categories:
Languages with multiple inheritance plus a few features to disambiguate special cases: virtual inheritance [C++], direct calls to all superconstructors in the most-derived class [C++], linearization of superclasses [Python], complex rules for super [Python], etc.
Languages with a differente concept, usually called interfaces, traits, mixins, modules, etc. that impose some limitations such as: no constructors [Java] or no constructors with parameters [Scala until very recently], no mutable fields [Java], specific rules for overriding (e.g. mixins take precedence over base classes [Ruby] so you can include them when you need a bunch of utility methods), etc. Java has become a language like these.
Why just by disallowing fields and constructors you solve many issues related to multiple inheritance?
You can't have duplicated fields in duplicated base classes.
The main class hierarchy is still linear.
You can't construct your base objects the wrong way.
Imagine if Object had public/protected fields and all subclasses had constructors setting those fields. When you inherit from more than one class (all of them derived from Object), which one gets to set the fields? The last class? They become siblings in the hierarchy, so they know nothing about each other. Should you have multiple copies of Object to avoid this? Would all classes interoperate correctly?
Remember that fields in Java are not virtual (overridable), they are simply data storage.
You could make a language where fields behave like methods and could be overridden (the actual storage would be always private), but that would be a much bigger change and problably wouldn't be called Java anymore.
Interfaces can't be instantiated by themselves.
You should always combine them with a concrete class. That eliminates the need for constructors and makes the programmer's intent clearer too (that is, what is meant to be a concrete class and what's an accessory interface/mixin). This also provides a well-defined place to solve all ambiguities: the concrete class.
That is mostly related to "diamonds problem" i think. Right now if you implement multiple interfaces with the same method, compiler forces you to override method the one you want to implement, because it don't know which on to use. I guess Java creators wanted to remove this problem back when interfaces couldn't use default methods. Now they came up with idea, that is good to be able to have methods with implementation in interfaces, as you can still use those as functional interfaces in streams / lambda expressions and utilize their default methods in processing. You cannot do that with classes but diamond problem still exist there. That is my guess :)
class A{
void m1(){
System.out.println("m1-A");
}
}
class B{
void m1(){
System.out.println("m1-B");
}
}
class C extends A, B{ // this will give an error
// inheritance means making all variables and/or methods available to the child class, here child class will get confused as which m1() method to inherit, hence an error
}
JAVA DOES SUPPORT MULTIPLE INHERITANCE.
If you make a OVERALL COMPARISON OF THE PROGRAMMING LANGUAGE,JAVA,THEN YOU COME TO KNOW THAT I AM TRUE.
Java's topclass or the root class in the Ancestor Hierarchy is the Object class.
This class is a Superclass of all other classes. Hence, each class in Java that we declare or is predefined in the API itself inherits this Object class.
Moreover, Java provides us to inherit one more class of our choice.
Hence, we can say that we are performing INTERLOCKED BUT MULTIPLE INHERITANCE.
2ND Way
Java supports Multiple Inheritance of Interfaces. So you can use as many interface implementations you want. But note, implementing an interface does not define IS A relationship as in case of Inheritance of Classes is possible.
Recently I started exploring Java 8 and I can't quite understand the concept of "functional interface" that is essential to Java's implementation of lambda expressions. There is a pretty comprehensive guide to lambda functions in Java, but I got stuck on the chapter that gives definition to the concept of functional interfaces. The definition reads:
More precisely, a functional interface is defined as any interface that has exactly one abstract method.
An then he proceeds to examples, one of which is Comparator interface:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
I was able to test that I can use a lambda function in place of Comparator argument and it works(i.e. Collections.sort(list, (a, b) -> a-b)).
But in the Comparator interface both compare and equals methods are abstract, which means it has two abstract methods. So how can this be working, if the definition requires an interface to have exactly one abstract method? What am I missing here?
From the same page you linked to:
The interface Comparator is functional because although it declares two abstract methods, one of these—equals— has a signature corresponding to a public method in Object. Interfaces always declare abstract methods corresponding to the public methods of Object, but they usually do so implicitly. Whether implicitly or explicitly declared, such methods are excluded from the count.
I can't really say it better.
Another explanation is given in the #FunctionalInterface page:
Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.
You can test which interface is a correct functional interface using #FunctionalInterface.
E.g.:
this works
#FunctionalInterface
public interface FunctionalInterf {
void m();
boolean equals(Object o);
}
this generates an error:
#FunctionalInterface
public interface FunctionalInterf {
void m();
boolean equals();
}
Multiple non-overriding abstract methods found in interface FunctionalInterf
Q. But in the Comparator interface both compare() and equals() methods are abstract, which means it has two abstract methods. So how can this be working, if the definition requires an interface to have exactly one abstract method? What am I missing here?
A.
A functional interface may specify any public method defined by Object, such as equals( ),
without affecting its “functional interface” status. The public Object methods are considered implicit
members of a functional interface because they are automatically implemented by an instance of a
functional interface.
An interface cannot extend Object class, because Interface has to have public and abstract methods.
For every public method in the Object class, there is an implicit public and abstract method in an interface.
This is the standard Java Language Specification which states like this,
“If an interface has no direct super interfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.”
That's how Object class' methods are declared in an interface. And according to JLS, this does not count as interface' abstract method. Hence, Comparator interface is a functional interface.
A functional interface has only one abstract method but it can have multiple default and static methods.
Since default methods are not abstract you’re free to add default methods to your functional interface as many as you like.
#FunctionalInterface
public interface MyFuctionalInterface
{
public void perform();
default void perform1(){
//Method body
}
default void perform2(){
//Method body
}
}
If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface’s abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.
Comparator is a functional interface even though it declared two abstract methods. Because one of these abstract methods “equals()” which has signature equal to public method in Object class.
e.g. Below interface is a valid functional interface.
#FunctionalInterface
public interface MyFuctionalInterface
{
public void perform();
#Override
public String toString(); //Overridden from Object class
#Override
public boolean equals(Object obj); //Overridden from Object class
}
Here is a "show me the code" approach to understanding the definition:
we shall look into OpenJDK javac for how it checks validity of classes annotated with #FunctionalInterface.
The most recent (as of July, 2022) implementation lies here:
com/sun/tools/javac/code/Types.java#L735-L791:
/**
* Compute the function descriptor associated with a given functional interface
*/
public FunctionDescriptor findDescriptorInternal(TypeSymbol origin,
CompoundScope membersCache) throws FunctionDescriptorLookupError {
// ...
}
Class Restriction
if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0 || origin.isSealed()) {
//t must be an interface
throw failure("not.a.functional.intf", origin);
}
Pretty simple: the class must be an interface and must not be a sealed one.
Member Restriction
for (Symbol sym : membersCache.getSymbols(new DescriptorFilter(origin))) { /* ... */ }
In this loop, javac goes through the members of the origin class, using a DescriptorFilter to retrieve:
Method members (of course)
&& that are abstract but not default,
&& and do not overwrite methods from Object,
&& with their top level declaration not a default one.
If there is only one method matching all the above conditions, then surely it is a valid functional interface, and any lambda will overwrite that very method.
However, if there are multiple, javac tries to merge them:
If those methods all share the same name, related by override equivalence:
then we filter them into a abstracts collection:
if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
.map(msym -> memberType(origin.type, msym))
.anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
abstracts.append(sym);
}
Methods are filtered out if:
their enclosing class is super class of that of another previously matched method,
and the signature of that previously matched method is subsignature of that of this method.
Otherwise, the functional interface is not valid.
Having collected abstracts, javac then goes to mergeDescriptors, which uses mergeAbstracts, which I will just quote from its comments:
/**
* Merge multiple abstract methods. The preferred method is a method that is a subsignature
* of all the other signatures and whose return type is more specific {#see MostSpecificReturnCheck}.
* The resulting preferred method has a thrown clause that is the intersection of the merged
* methods' clauses.
*/
public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) {
// ...
}
Conclusion
Functional interfaces must be interfaces :P , and must not be sealed or annotations.
Methods are searched in the whole inheritance tree.
Methods overlapping with those from Object are ignored.
default methods are ignored, unless they are later overridden by sub-interfaces as non-default.
Matching methods must all share the same name, related by override equivalence.
Either there is only one method matching the above conditions, or matching methods can get "merged" by their class hierarchy, subsignature relations, return types and thrown clauses.
The Java docs say:
Note that it is always safe not to override Object.equals(Object).
However, overriding this method may, in some cases, improve
performance by allowing programs to determine that two distinct
comparators impose the same order.
Maybe Comparator is special? Maybe, even though it's an interface, there is somehow a default implementation of equals() that calls compare()? Algorithmically, it's trivial.
I thought all methods that were declared in interfaces were abstract (i. e. no default implementation). But maybe I'm missing something.
Definition:
If an interface contains only one abstract method, then such type of interface is called functional interface.
Usage:
Once we write Lambda expression "->" to invoke its functionality ,
then in this context we require Functional Interface.
We can use the Functional Interface reference to refer Lambda
expression.
Inside functional interface we can have one abstract method and n
number of default/static methods.
Functional interface with respect to inheritance:
If an interface extends Functional interface and the child interface does not contain any abstract method , then the child interface is also considered to be Functional Interface.
Functional interface is not new to java, its already used in following interface API's:
Runnable : contains run() method only.
Callable : contains call() method only.
Comparable : contains compareTo() method only.
Before Java 8, an interface could only declare one or more methods also known as Abstract Method (method with no implementation, just the signature). Starting with Java 8 an interface can also have implementation of one or more methods (knows as Interface Default Method) and static methods along with abstract methods. Interface Default Methods are marked default keyword.
So the question is, what is Functional Interface?
An interface with Single Abstract Method (SAM) is called Functional Interface.
Which means -
An interface with Single Abstract Method is a Functional Interface
An interface with Single Abstract Method and zero or more default
methods and zero or more static method is also a valid Functional
Interface.
More detail with example code https://readtorakesh.com/functional-interface-java8/
As a rule, in the context of a large project, is it considered safe to take make an existing, ubiquitously used interface into a functional interface?
E.g., given an existing interface and class:
public interface Interface {
public double calculateSomething(double x);
public void doSomething();
}
which is implemented by
class InterfaceImplementer implements Interface {
public double calculateSomething(double x) {
return 2 * x;
}
public void doSomething() {
// insert specific behavior here
}
}
can I safely change the interface by defining all but one method as default:
public interface Interface {
public double calculateSomething(double x);
default void doSomething() {
// insert some default behavior here
}
}
So that I can go from defining an object as
Interface object = new InterfaceImplementer() {
#Override
public double calculateSomething(double x) {
return 2 * x;
}
};
to
Interface object = (x) -> 2 * x;
while still being able to define objects in the old, tedious way.
From what I can tell, this runs no risk of upsetting any existing code, and I've made such a change to a large project and had no runtime or compile errors. But I want some confirmation whether this matches up with common knowledge and best practices.
Any interface that only has a single non-default method (only one method needs to be implemented in a class) is by definition a functional interface. This is a good rule!
However, a #FunctionalInterface annotation has the advantage of enforcing the "only one method in the interface for a functional interface"-rule. So if you added it to your original two-method interface, you would have gotten a compiler error. Therefore by explicitly adding #FunctionalInterface you declare your intent and make your code more clear to future maintainers.
On java code level, I can think of one problem: since this interface already had contained 2 methods at some point in the past, you may want to add another method to it later on. You won't be able to add another method to a functional interface, since it has to remain a functional interface so you can use it as a functional interface. You will have to create an interface that inherits from this one. Which leads me to the main point.
It may have been logical to have those 2 methods in one interface before, but is it really logical now? Refactor the code, separate the interfaces; either make one extend another or use an interface that inherits from both, your call. If the interface is to be used as a functional one, make it functional. It will be clean. It will be understandable. You will be able to add methods to one of those interfaces in the future without further refactoring.
The Java API states:
However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.
Therefore there is no risk to add that annotation.
Well, it's not the #Functional that might break anything, but adding a default implementation may lead to compilation errors for abstract classes that implement or interfaces that extend multiple interfaces declaring methods with override-equivalent signatures:
The following compiles fine:
interface I {
void a();
}
interface J {
void a();
}
interface K extends I, J {}
while this doesn't:
interface I {
default void a() {}
}
interface J {
void a();
}
interface K extends I, J {}
The default method a() inherited from I conflicts with another method inherited from J
So if you do this in a library, code using this may fail to compile after the change.
I have a simple Java question. Consider the following interfaces:
interface A {
void work();
void a();
}
interface B {
void work();
void b();
}
So when a class is going to implement them, it should be like this:
class Impl implements A, B {
void work() {
/*some business*/
}
void a() {}
void b() {}
}
My question is, in work method, how would I find out that, it has invoked by type A or B?
The above class in C# would be like this, and this separates both implementations very well:
class Impl : A, B
{
void B::work() {}
void A::work() {}
void a() {}
void b() {}
}
But how would I achieve something like C# model in Java?!
Thanks in advance.
Neither. The idea of an interface is that a class that implements it, agrees with the "contract" the interface implies. If you have two interfaces, requiring both to implement a method work(), and a class that implements both interfaces, then it has to implement work() to agree with the contract of both.
The JavaDoc says:
Implementing an interface allows a class to become more formal about
the behavior it promises to provide. Interfaces form a contract
between the class and the outside world, and this contract is enforced
at build time by the compiler. If your class claims to implement an
interface, all methods defined by that interface must appear in its
source code before the class will successfully compile.
And that is exactly what you do by implementing a work() method: you satisfy both interfaces A and B.
Your interface only tells you the signatures of the methods that the implementing class needs to provide. In your example both A and B ask for a method work() that has void as return type. So basically they are both asking for the same method. I don't see how you could or would need to differentiate?
You might have a problem with diamand implementation.
You need to specified it by your own.
void work() { A.super.work(); } // or B.super.work();
The method work will satisfy the requirements of both interfaces. The method is contained on the class, which can instantiate both interfaces. In order to implement the interface the class must possess the methods specified in the interface. It does not matter if the same method is used to satisfy the requirements of multiple interfaces.
JVM will not be invoking A or B, but only the implementation Impl. You can cast back to A or B and your client can invoke methods based on the methods available in the specific interface.
As
SeekableByteChannel is an interface,how are we invoking its methods from Files class's newByteChannel method.
I Know how to invoke it .But i cant understand the concept because an interface doesn't implements the behavior
1 more Question.I have seen many times in java example code that interface methods are invoked or called.But as far as i know interface doesn't initialize or implements the methods.
SeekableByteChannel idd = Files.newByteChannel(file);
idd.size();
How does the above code works because SeekableByteChannel is an interface and Files class doesn't implement the methods of SeekableByteChannel .So where SeekableByteChannels methods are initialized.
Please Help
An interface in Java is nothing more but a contract; at the compiler level, the only contract is that if you implements an interface, you must have an implementation of all methods (for classes which are not abstract):
public interface Foo
{
/*
* Any invocation of this method sends the instance to the moon
*/
void foo();
}
If you have a concrete class which you can instantiate and which implements Foo, such as:
public class MyClass
implements Foo
{
// must implement foo()
#Override
public void foo() { stayOnEarth(); }
}
then you can do:
final Foo foo = new MyClass();
As you have a reference to an instance of type Foo, it means you can invoke foo() on it:
foo.foo();
The JVM will look up method foo() and find it.
Now: the fact that you have implemented foo() is one thing; the fact that you obey the contract of this interface is another. The compiler does not give a <beep> if you stay on Earth or go right to Antares: it cannot enforce that.
This is a question of trust first and foremost: if you implement an interface, you are expected to understand what this interface means; which is why there is documentation. The compiler cannot help any further but to enforce that you at least implement the needed methods.
It seems your underlying question is how do interfaces work. The common buzzword that goes with interfaces is "contract". If your class implements an interface, it implements this contract. The contract means that the class MUST define the functions declared in the interface. Thus if we have -
Interface InterfaceTest{
void foo();
}
Class Implementer implements InterfaceTest{
the class Implementer MUST implement the function foo() or there will be a compiler error -
void foo(){
//Do stuff.
}
Note that Files does not implement SeekableByteChannel. So Files does not have any relation to it. Thus Files can have any functions it wants, including ones in SeekableByteChannel without issue.