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.
Related
Or in particular: What is the difference between
interface A {
void fa();
}
interface B extends A {
void fa();
void fb();
}
and
interface A {
void fa();
}
interface B extends A {
#Override
void fa();
void fb();
}
Does it effect the implementing class in any way?
No it should not. The class that implements interface B will still have to provide an implementation of void fa(); regardless whether interface B annotates the same method signature with #Override or not. Also, putting the #Override annotation in interface B doesn't make a lot of sense in this case because the annotation basically means that you are overriding the implementation that the super class gave to that method signature. Since Interface A nor Interface B provides an implementation to void fa() it doesen't make sense.
It would make sense if interface A provided a default implementation to void fa() For example:
interface A {
public default void fa(){
System.out.println("My default implementation");
}
}
In this case Interface B would be overriding the implementation given to fa() from Interface A by making it abstract again. The same goes when Interface A defines fa() as abstract and Interface B gives it an implementation by turning it into a default method.
The #Override annotation is just a reminder to the compiler to show you an error if you define something wrong. It doesn't affect anything. The good practise is to write it always.
Adding or omitting #Override doesn't change the overriding behaviour of the fa method. It's an override based on the name and parameter types (in this case none), nothing else. The return type needs to be compatible (covariant return), but is not part of the "is this an override or not" decision.
The #Override annotation is (mostly) used to verify that a method is overriding a method from a super type. If you omit it, there may be a warning from your IDE or other tooling like SonarQube, but the compiler doesn't care. If you add it incorrectly, that's when its true purpose kicks in - you'll get a compiler error.
I want to create a class that does not implement any method of an interface, but extends any implementation of A with it's own methods.
Let's assume we have the following:
public interface A {
public void a();
}
and
public class B implements A {
#override
public void a() {
System.out.println("a");
}
}
I now want to create a class C that also implements A and takes another random implementation of A:
public class C implements A {
public C(A a) {
//what do I need to do with a here?
}
public void c() {
System.out.println("c");
}
}
Now if I have the following:
A b = new B();
A c = new C(b);
c.a();
The output should be "a".
I can't just
public class C extends B {
...
as C is supposed to be able to work with any implementation of A, not just B.
I also can't
public class C implements A {
private a;
public C(A a) {
this.a = a;
}
#override
public void a() {
a.a();
}
public void c() {
System.out.println("c");
}
}
since that would mean that I have to redirect every single interface method and rewrite C whenever something changes with A.
Is there any way to handle that problem in Java?
For another example, replace A: List; B: ArrayList; C: FooList; a(): size()
What you're looking for is a dynamic proxy, which automatically implements all the methods of an interface by delegating to a concrete implementation of this interface. That's not trivial, but not so complex to do either, using Java's Proxy class.
A concrete example of such a proxy, which "adds" methods to any instance of PreparedStatement by wrapping it, can be found at https://github.com/Ninja-Squad/ninja-core/blob/master/src/main/java/com/ninja_squad/core/jdbc/PreparedStatements.java
Unfortunately, there's no way to do it in Java, other than your last code snippet. Various IDEs will help you with the code generation, though, and marking all methods #override will mean that you'll get a warning or an error if your implementation of C doesn't exactly match A's interface.
For Eclipse (and, apparently, IntelliJ), see the "Generate Delegate Methods" command.
This is probably not going to immediately help you, but if you used Java 8, you could solve this with defender methods, which are methods implemented in the interface.
You would then, for each existing implementation class, add your own class which extends the class and implements your additional interface with the defender methods. The methods would be "mixed into" your class.
Java 8 is just around the corner, though, so it is not a far-off solution. Oracle has promised it will release it by the end of this quarter, meaning in less than a month and a half at the latest.
Is there any way to handle that problem in Java?
Basically, no.
What you are describing a wrapper class that delegates calls to the wrapped method. The only way you can implement that (in regular Java) is to implement all of the methods and have them make the calls.
Another alternative would be to use the Proxy class ... which will effectively generate a dynamic proxy. The problem is that this requires an InvocationHandler that will (I guess) use reflection to make the call to the wrapped object. It is complicated and won't be efficient.
If your goal is simply to avoid writing code, I think this is a bad idea. If your goal is to writing the same code over and over (e.g. because you have lots of exampled of C for a given A), then consider coding an abstract class for the C classes that deals with the wrappering / delegation.
It would also be possible to generate the wrapper class C from nothing, using the BCEL library or similar. But that's an even worse idea (IMO).
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.
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.
What I mean is:
interface B {...}
interface A extends B {...} // allowed
interface A implements B {...} // not allowed
I googled it and I found this:
implements denotes defining an implementation for the methods of an interface. However interfaces have no implementation so that's not possible.
However, interface is an 100% abstract class, and an abstract class can implement interfaces (100% abstract class) without implement its methods. What is the problem when it is defining as "interface" ?
In details,
interface A {
void methodA();
}
abstract class B implements A {} // we may not implement methodA() but allowed
class C extends B {
void methodA(){}
}
interface B implements A {} // not allowed.
//however, interface B = %100 abstract class B
implements means implementation, when interface is meant to declare just to provide interface not for implementation.
A 100% abstract class is functionally equivalent to an interface but it can also have implementation if you wish (in this case it won't remain 100% abstract), so from the JVM's perspective they are different things.
Also the member variable in a 100% abstract class can have any access qualifier, where in an interface they are implicitly public static final.
implements means a behaviour will be defined for abstract methods (except for abstract classes obviously), you define the implementation.
extends means that a behaviour is inherited.
With interfaces it is possible to say that one interface should have that the same behaviour as another, there is not even an actual implementation. That's why it makes more sense for an interface to extends another interface instead of implementing it.
On a side note, remember that even if an abstract class can define abstract methods (the sane way an interface does), it is still a class and still has to be inherited (extended) and not implemented.
Conceptually there are the two "domains" classes and interfaces. Inside these domains you are always extending, only a class implements an interface, which is kind of "crossing the border". So basically "extends" for interfaces mirrors the behavior for classes. At least I think this is the logic behind. It seems than not everybody agrees with this kind of logic (I find it a little bit contrived myself), and in fact there is no technical reason to have two different keywords at all.
However, interface is 100% abstract class and abstract class can
implements interface(100% abstract class) without implement its
methods. What is the problem when it is defining as "interface" ?
This is simply a matter of convention. The writers of the java language decided that "extends" is the best way to describe this relationship, so that's what we all use.
In general, even though an interface is "a 100% abstract class," we don't think about them that way. We usually think about interfaces as a promise to implement certain key methods rather than a class to derive from. And so we tend to use different language for interfaces than for classes.
As others state, there are good reasons for choosing "extends" over "implements."
Hope this will help you a little what I have learned in oops (core java) during my college.
Implements denotes defining an implementation for the methods of an interface. However interfaces have no implementation so that's not possible. An interface can however extend another interface, which means it can add more methods and inherit its type.
Here is an example below, this is my understanding and what I have learnt in oops.
interface ParentInterface{
void myMethod();
}
interface SubInterface extends ParentInterface{
void anotherMethod();
}
and keep one thing in a mind one interface can only extend another interface and if you want to define it's function on some class then only a interface in implemented eg below
public interface Dog
{
public boolean Barks();
public boolean isGoldenRetriever();
}
Now, if a class were to implement this interface, this is what it would look like:
public class SomeClass implements Dog
{
public boolean Barks{
// method definition here
}
public boolean isGoldenRetriever{
// method definition here
}
}
and if a abstract class has some abstract function define and declare and you want to define those function or you can say implement those function then you suppose to extends that class because abstract class can only be extended. here is example below.
public abstract class MyAbstractClass {
public abstract void abstractMethod();
}
Here is an example subclass of MyAbstractClass:
public class MySubClass extends MyAbstractClass {
public void abstractMethod() {
System.out.println("My method implementation");
}
}
Interface is like an abstraction that is not providing any functionality. Hence It does not 'implement' but extend the other abstractions or interfaces.
Interface is the class that contains an abstract method that cannot create any object.Since Interface cannot create the object and its not a pure class, Its no worth implementing it.