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.
Related
Although the class B implements the interface A, it does not provide the implementation of the method show(). Again, D extends C but in class D the implementation of displayNothing() is the same as the implementation of displayNothing() method in its superclass C.
But in both the cases #Override annotation work properly, why?
//code snippet 1
interface A
{
void show();
}
abstract class B implements A
{
#Override
abstract public void show();
}
//code snippet 2
class C
{
void displayNothing()
{
}
}
class D extends C
{
#Override
void displayNothing()
{
}
}
#Override is only bothered with whether your function name along with the data type is just the same as the method in your super class (with no Alphabetical error). In your case it is the same.Try changing void as int in your class D. It shows a compilation error. As for your abstract class method, it needn't define anything coz the name says it all, it is abstract.
The purpose of the #Override annotation is to prevent bugs. It's presence informs the compiler that there must be a inherited method with that same exact signature that this class is overriding. It does matter if there is an implementation of a method or not.
It is perfectly legal to not include an #Override annotation. The potential problem you might encounter, though, is if you accidentally had a typo or inadvertently changed the method signature, you would be overloading the method, not overriding it. The compiler would not be able to catch this bug. The program might crash or it might even run, but run incorrectly.
Because this might be a difficult bug to spot, especially with methods containing several parameters, the #Override annotation was created. The #Override annotation informs the compiler that this method is an override, not an overload and if the compiler fails to find a method to override, return a compilation error.
All these methods would compile and could be run but none would override the displayNothing() method.
void displayNothng();
void displaynothing();
void displayNothing(String value);
The #Override annotation "works properly" in both presented cases, because java reuses this annotation for interfaces and classes, even if you feel that the first and the second snippet of code do something different it's just not as important to introduce separated keywords/annotations to differentiate between overriding from an interface and from a class. Even an abstract class doesn't change things here.
The #Override indicates that a given method has a compatible representation in the super class/interface, it's used to ensure we don't have any syntax issue in the definition.
B is abstract. Abstract classes don’t need to provide implementations. If an abstract class doesn’t implement a required method it doesn’t matter. If a class isn’t abstract, then implementations of all abstract methods need to be there.
D provides an override of the displayNothing method in C. The compiler doesn’t check whether the overridden version is the same as the overriding version, and it doesn't care if the overriding implementation is empty. All the Override annotation does is confirm that there is a method with the same signature above the annotated one in the class hierarchy.
The purpose of the annotation is to confirm that you’re actually overriding an existing method and haven’t introduced a bug by misspelling the method name or otherwise not matching the signature of the method you mean to override. See the Java Language Specification, 9.6.4.4, where it says:
Programmers occasionally overload a method declaration when they mean to override it, leading to subtle problems. The annotation type Override supports early detection of such problems.
The classic example concerns the equals method. Programmers write the following in class Foo:
public boolean equals(Foo that) { ... }
when they mean to write:
public boolean equals(Object that) { ... }
This is perfectly legal, but class Foo inherits the equals implementation from Object, which can cause some very subtle bugs.
(Be aware when I describe what #Override does I'm skipping over override-equivalence because you didn't ask about it and there are already perfectly good answers that cover that.
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.
Why can't I create a #FunctionalInterface with a default method implementation?
#FunctionalInterface
public interface MyInterface {
default boolean authorize(String value) {
return true;
}
}
You can have default methods in a functional interface but its contract requires you to provide one single abstract method (or SAM). Since a default method have an implementation, it's not abstract.
Conceptually, a functional interface has exactly one abstract method.
Since default methods have an implementation, they are not abstract.
and
If a type is annotated with this annotation type, compilers are
required to generate an error message unless:
The type is an interface type and not an annotation type, enum, or
class.
The annotated type satisfies the requirements of a functional
interface.
Here you don't satisfy the functional interface's requirement, so you need to provide one abstract method. For example:
#FunctionalInterface
interface MyInterface {
boolean authorize(int val);
default boolean authorize(String value) {
return true;
}
}
Note that if you declare an abstract method overriding one of a public method from the Object's class it doesn't count, because any implementation of this interface will have an implementation of those methods through at least the Object's class. For example:
#FunctionalInterface
interface MyInterface {
default boolean authorize(String value) {
return true;
}
boolean equals(Object o);
}
does not compile.
A functional interface is an interface having a single abstract method. The entire purpose of defining functional interfaces is to enable the implementation of the single abstract method via lambda expressions which will effectively override that method which makes providing a default implementation for it pointless.
Having an interface consisting entirely of default methods raises multiple problems. There is the technical problem that the compiler can’t decide for a lambda expression which method to implement when there are multiple default methods and there is the semantic problem that an interface consisting entirely of default methods is not abstract. You can’t instantiate this default behavior as you can’t instantiate interfaces and are forcing programmers to create concrete classes just to invoke the default behavior, which, since interfaces are stateless, could be provided by a singleton instead:
#FunctionalInterface
public interface MyInterface {
static MyInterface DEFAULT = s->true;
boolean authorize(String value);
}
Note that you can have interfaces extending a functional interface and providing a default method, if you need. Still, if this results in creating an interface having no abstract methods I would question the design. You may compare with the discussion about marker interfaces with default methods. If the sub-interface will have different abstract methods than the functional interface, it’s a different story. There might be real use cases for this, but these sub-interfaces will also demonstrate why they shouldn’t be mixed with the functional base interface as a lambda expression will always implement the abstract method.
That's because #FunctionalInterface can have default methods, as many as you want. For example, consider the java.util.Function interface. It contains two default methods: compose and andThen. But there should be exactly one non-default method. Otherwise how compiler would know which of your default methods should be mapped to lambda?
I just want to add a few more points.
We can have any number of Abstract method in FuntionalInterface.
We can also have any number of Static method in FuntionalInterface.
We can also declare an abstract method overriding one of a public method from the Object's class but there must be some other custom abstract method in this functional interface too as shown in below code
#FunctionalInterface
public interface SAM {
public void helloSam();
default void xyz() {
System.out.println("xyz");
}
static void abc() {
System.out.println("abc");
}
static void abc1() {
System.out.println("abc1");
}
default void xyz1() {
System.out.println("xyz1");
}
boolean equals(Object o);
}
Suppose I am designing something like the following interface:
public interface MyInterface{
public MyInterface method1();
public void method2(MyInterface mi);
}
However, there is the caveat that the return type for method1 and the parameter for method2 match the concrete implementation and not just MyInterface. That is, if I have MyInterfaceImpl that implements MyInterface, it needs to have the following:
public class MyInterfaceImpl implements MyInterface{
#Override
public MyInterfaceImpl method1(){...}
#Override
public void method2(MyInterfaceImpl mi){...}
}
As written above, method1 won't cause any compile errors, but there is nothing guaranteeing that the return type matches in all implementations. Of course method2 won't even compile because the signature does not match the interface.
One candidate solution is to use self-referential or recursive bounds in generics:
public interface MyInterface<T extends MyInterface<T>>{
public T method1();
public void method2(T mi);
}
public class MyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
#Override
public MyInterfaceImpl method1();
#Override
public void method2(MyInterfaceImpl mi);
}
This would get me what I want with one exception: other implementations might pass the wrong generic type (nothing forces T to match the concrete type). So potentially someone else could implement the following:
public class NotMyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
#Override
public MyInterfaceImpl method1();
#Override
public void method2(MyInterfaceImpl mi);
}
That would compile just fine even though NotMyInterfaceImpl should implement MyInterface<NotMyInterfaceImpl>.* That makes me think I need something else.
*Note that I don't think I'm trying to violate LSP; I'm OK with the return type/parameter being subclasses of NotMyInterfaceImpl.
So I don't know of a clean way to do this. That leads me to believe that I might be focusing too much on implementation details in the interface, but it doesn't seem that way to me. Is there any way to do the type of thing I described, or is this some kind of smell that I'm putting something in an interface that doesn't belong there?
This is the exact situation faced by the Comparable interface (its compareTo method wants to take an argument the same type as the object it is called on). So what does it do? It's simply defined as Comparable<T>. The idea is that an implementing class "should" implement Comparable with itself as the parameter (allowing it to "compare to" itself); but this is not enforced (since there is no way to do it).
Yes, as you noted, this will allow any class to implement Comparable with a parameter of any other class: class Foo implements Comparable<Bar> where Foo and Bar have no relation to each other. However, this is not really a problem.
All the methods and classes (sorting, maximum, etc.) that require Comparable objects have the following generic type constraint <T extends Comparable<? super T>>. This ensures that objects of type T are comparable with themselves. That way, it is completely type-safe. So the enforcement is not made in the declaration of the Comparable interface, but in the places that use it.
(I notice that you use <T extends MyInterface<T>> while Comparable uses simply <T>. Although <T extends MyInterface<T>> will exclude cases where the type parameter does not implement MyInterface, it will not exclude cases where the type parameter does implement MyInterface, but is different than the class. So what's the point of half-excluding some cases? If you adopt Comparable's way of restricting it where they are used, it's type-safe anyway, so there is no point in adding more restrictions.)
I believe that this cannot be done. There is simply no way to refer to an object's implementation class in the framework of generics, nor, as far as i know, any way to construct a cage out of pure generics which is capable of constraining the implementation class to match a type parameter.
The most useful thing i can suggest is using a self-referential parameter, and then always acquiring instances of implementations from factory methods which look like:
public <T extends MyInterface<T>> T newInstance();
It is easier for a camel to pass through the eye of a needle than for an instance of NotMyInterfaceImpl to pass through that return type. So, although troublemakers could write classes which do not conform to your masterplan, they couldn't return them from factories. Unless NotMyInterfaceImpl extended MyInterfaceImpl; but then, in a sense, it would also be a MyInterfaceImpl, so perhaps that would be kosher?
EDIT: A slightly more useful version of that idea is to always pass instances of implementations of the interface around in a suitably restrictive holder, like:
class Holder<T extends MyInterface<T>> {
public final T value;
}
If someone gives you a Holder<Q>, then you know that Q must be a version of MyInterface bound to itself, which is what you're after.
The point of returning the interface is such that the method does not care the actual implementation of the returned object. In your case you actually want to mandate the type to be a particular sub-implementation of that interface.
To apply the constraints that you described above, IMHO the design should probably be a base class instead of an interface. This allows you to control the implementation, for example a top-level flow, and leave low-level strategy to sub-classes to implement:
class MyBaseImpl {
public final void fixedFlow() {
MyBaseImpl obj = method1();
obj.method2(this);
}
protected abstract MyBaseImpl method1();
....
}
There has to be other methods to make it interesting...; perhaps you have good reasons to want to do this...
Hope this helps!
What you are trying to do is not legal because you are trying to narrow the parameter of the implemented type, and this "does not make sense". You are tryint to use "covariant" parameters, and only covariant return types are allowed (and even logic, and only supported from Java 5).
I mean, if it was possible to use covariant parameter types, you could do things like:
MyInterface instance = new MyInterfaceImpl();
And then, invoke on "instance" the method with another implementation supported by the interface but not supported by the MyInterfaceImpl class this way:
instance.method2(new MyInterfaceImpl_2());
Java cannot convert MyInterfaceImpl_2 to MyInterfaceImpl, so it prevents you from doing so at compilation time.
What you could do is to widen the parameter, using "contravariant" parameter, which would be logic. For more detail on this, check this anser:
Demonstrate covariance and contravariance in Java?
The only workaround that I can think of, is to solve the problem at runtime, I mean, doing something like this:
public class MyInterfaceImpl implements MyInterface{
#Override
public void method2(MyInterface mi){
realMethod((MyInterfaceImpl) mi);
}
public void realMethod(MyInterfaceImpl) {...}
}
But you could get ClassCast exception, of course.
Is this what you are looking for?
public interface MyInterface {
static abstract class MyInterfaceImpl implements MyInterface {
#Override
public abstract MyInterfaceImpl method1();
#Override
public abstract void method2(MyInterfaceImpl mi);
}
MyInterfaceImpl method1();
void method2(MyInterfaceImpl mi);
}
And you could even implement method 1 or 2 instead of making them abstract.
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.