While reading JLS Specification for Interfaces I came across following phrase:
If an interface has no direct superinterfaces, 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.
So My question is when we implement an interface why we are not forced to override implicit methods which are declared in Object class even though they are implicitly defined as abstract in Interface.
Hope I put myself correctly.
Thanks.
All classes implicitly extend Object, either directly or through some chain of superclasses. Thus, you don't have to explicitly override the implicit methods declared in an interface because you inherited the implementations from Object.
The point of an interface is to force you to implement some method. The reason everything extends Object is that we want to have some way of dealing with all classes independent of implementation. There is no reason that each class should implement something like getClass(), because the behaviour is always going to be the same.
Related
This question already has an answer here:
How methods of Object class be visible through interface?
(1 answer)
Closed 1 year ago.
According to The Java Language Specification, Java SE 16 Edition (JLS) §9.2 Interface Members:
If an interface has no direct superinterface types, 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 (§4.3.2), unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
Why does any top-level Interface “implicitly” declare the public methods of the Object class? What is the purpose of this design?
What is the purpose of this design?
Because you want to be able to call all the Object methods ( toString, equals, hashCode, and such) on every object of any type.
interface Foo {
}
Foo foo = ...;
foo.equals(otherFoo);
Doesn't matter if I actually declared the equals method in the interface.
Every class is implicitly a subclass of Object
See: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html for more
Definitions: A class that is derived from another class is called a subclass (also a derived class, extended class, or child class). The class from which the subclass is derived is called a superclass (also a base class or a parent class).
Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object.
Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object.
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/
When I implement an Interface in Java, for instance:
public interface IColumnHeader {
public String getHeaderValue();
public String findColumnValueFromHeaderValue(String parseFrom);
}
the following enum implements the above interface:
public enum FileColumnDwellTime implements IColumnHeader {
REPORTER_USER_ID {
#Override
public String getHeaderValue() {
return "reporter_user_id";
}
#Override
public String findColumnValueFromHeaderValue(String parseFrom) {
return parseFrom;
}
};
}
Why does implementing an interface in Java and implementing the methods from the interface introduce the #Override annotation. Isn't that a total misnomer?
Shouldn't that annotation actually be called something like "#Implementation"?
The #Override annotation would be more apt for subclasses that actually override superclass methods that are predefined. In the case of simply implementing a method from an interface, there is no actual overriding being done.
Am I right?
(If I were the JLS writers for Java 9, I would have a new annotation called #Implementation that would "subclass" the #Override annotation, in the case of implementing methods from interfaces, and the like.)
Taking a look at the JLS, it just seems to be how it's defined. I'm looking at JLS 8, not sure if the section I'm going to quote was different in earlier versions (although I highly doubt it will, since interface interactions shouldn't have changed). From section 8.4.8.1:
An instance method mC declared in or inherited by class C, overrides from C another
method mI declared in an interface I, iff all of the following are true:
I is a superinterface of C.
mI is an abstract or default method.
The signature of mC is a subsignature (§8.4.2) of the signature of mI.
So at least based on this, the #Override annotation makes sense, since it denotes an instance method that overrides a method declared in an interface, based on the definitions in the JLS.
Unfortunately, I can't give an authoritative answer as to why this is called overriding, but here's sort of how it works in my head:
If you inherit an abstract method (like one in an interface), your class implicitly contains the signature for that method in its body. When you implement the method corresponding to that signature, you replace (and thus override) the inherited abstract method signature with one corresponding to a concrete implementation. So it makes sense to have #Override, right?
In addition, this way #Override would work for overridden methods regardless of whether they were technically an implementation or "truly" overridden. And why make more work for yourself (and compiler designers) than you have to?
I know that that's a rather bad view of how inheritance works, but I hope it makes sense.
So I guess in the end, I would say you are wrong. There is overriding being done. But I wouldn't say it's immediately obvious why that is the case. Interesting question!
Does interfaces and abstract classes in Java extend base Object class? Logical answer which I can think of is no, but if interface does not extend Object class, then can please someone explain me the below code:
interface A {
#Override
public int hashCode();
#Override
public String toString();
}
In above case, A interface is the new interface declared. Yet, no class is implementing it. Then how come the methods from Object class visible in the interface?
If it doesn't extend Object class, then why I can't declare following method in the interface:
public Class getClass();
When I tried to declare this method in the interface, it says that it can't override this method, inherited from Object class, as it is declared as final method in Object class.
Interface could only extend some other interface and no - there is no some root interface. Abstract class, as any other class in Java, has Object as its ancestor - while it may not be a direct parent.
Methods, marked as final, could not be overriden in successor classes. As your class has Object as its ancestor - this rule also applies here.
The reason this is can be found in JLS $9.2
If an interface has no direct superinterfaces, 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.
It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
And as seen in Object#getClass:
public final Class<?> getClass()
Interfaces do not inherit from Object, but they do mimick the methods available by implicitly adding them. Likewise here, a final method in that base interface can't be overridden in your self-defined interface.
As you know, in a java interface, all methods have to be defined as abstract. But when I define a method as not typing abstract, the compiler says it is okay. I know that an abstract method must not have a body. Does a method somewhere in an interface necessarily have a name abstract or not? : What i mean is, what is the difference between:
public interface blabla {
public void aMethod();
//or
public abstract void aMethod();
}
No, marking an interface method as abstract has no meaning and is never required.
All interface methods are implicitly abstract (and public too btw).
From the JLS:
Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block.
Every method declaration in the body of an interface is implicitly public.
For compatibility with older versions of the Java platform, it is permitted but discouraged, as a matter of style, to redundantly specify the abstract modifier for methods declared in interfaces.
It is permitted, but strongly discouraged as a matter of style, to redundantly specify the public modifier for interface methods.
Related question (+ answer with a historical reference to a statement saying that abstract was once required for interface methods):
Java abstract interface
See the sample example below
interface xyz
{
void methodA();
}
Save this to xyz.java
Now compile this using javac tool
and then use the command given belo
javap xyz
the output would be
Compiled from "xyz.java"
interface xyz {
public abstract void methodA();
}
That means when you compile an interface, compiler makes its signature to public and abstract by default.
So it is not necessary to use abstract keyword for any method of interface.
I don't know that they have to be defined as abstract. Probably because they don't. See Oracle's tutorial.
you don't need to specify abstract (default) because within an interface it does not make sense as all the method of the interface needs to be implemented
All methods in an interface are abstract by definition.
You can't create an object out of an interface (e.g., using Interface i = new Interface();) so there's no difference between marking a method as abstract or not.
Any class that implements the interface needs to decide whether to implement it or to let a subclass do it. So as far as the interface is concerned, all methods are abstract by default.
An abstract method provides no implementation. A class which has an abstract method is necessarily abstract, which means that you cannot create instances of this class. To create an instance of that class, you need to subclass and provide non-abstract overwrites for the abstract methods.
An interface never provides an implementation of its methods and it cannot be instantiated. Therefore every method of an interface is per definition abstract. You do not need to provide the keyword abstract when declaring a method in an interface. And by convention the keyword abstract is not used within an interface.
The methods of an interface don't have to be explicitly defined as abstract because they are implicitly abstract and public as defined in the Java Language Specification §9.4. A redundant declaration is perfectly legal though.
If you forgot to put abstract keyword before interface method, Java will implicitly put public abstract keyword before it. Because all interface methods must be abstract.