This question already has answers here:
Multiple inheritance for an anonymous class
(6 answers)
Closed 4 years ago.
It is clearly stated that interfaces don't have constructors. But when using anonymous inner classes we create an interface object and do overriding it methods. If there is no constructors in interfaces how this is possible.
For an example,
interface A{
void print();
}
class B{
public static void main(String args[]){
A a=new A(){
void print(){
System.out.println("Message");
}
};
}
}
How that A a=new A() is possible if interface is not having constructors?
The code
interface A {
void print();
}
class B {
public static void main(String[] args) {
A a = new A() {
public void print() {
System.out.println("Message");
}
};
}
}
is a shorthand for
interface A {
void print();
}
class B {
public static void main(String[] args) {
class B$1 extends java.lang.Object implements A {
B$1() {
super();
}
public void print() {
System.out.println("Message");
}
}
A a = new B$1();
}
}
With just one exception: If class B$1 is declared explicitly, it is possible to extend from it using class C extends B$1. However, it is not possible to extend from an anonymous class B$1 (JLS §8.1.4), even though it is not final (JLS §8.1.1.2).
That is, anonymous classes are still classes. As all classes (except java.lang.Object itself), even these classes extend java.lang.Object, directly or indirectly. If an anonymous class is specified using an interface, it extends java.lang.Object and implements that interface. If an anonymous class is specified using a class, it extends that class. In case the constuctor has arguments, the arguments are forwarded to super().
You can even (although definitely not recommended at all) insert a A a2 = new B$1(); later in main(), if you like. But really, don't do that, I'm just mentioning it to show what's going on under the hood.
You can observe this yourself by putting your source code in a separate directory, say, into AB.java, compile it, and then
look at the class files that were generated.
Use javap -c B$1 to see how the anonymous class was generated by javac.
Every class has a default constructor which is the no-argument constructor if you don't define another constructor. And the anonymous class implement the interface will automatically generate it unless you define another constructor.
Related
This question already has answers here:
Creating the instance of abstract class or anonymous class
(8 answers)
abstract class and anonymous class [duplicate]
(2 answers)
Closed 3 years ago.
I have been reading this guide on inner classes and came across this interesting example of an anonymous class.
So, by default we cannot instantiate an abstract class, e.g.
abstract class AnonymousInner {
public abstract void mymethod();
}
public class Outer_class {
public static void main(String args[]) {
AnonymousInner inner = new AnonymousInner();
inner.mymethod();
}
}
Gives an error stating that we cannot instantiate an abstract class.
But doing it this way is fine -
abstract class AnonymousInner {
public abstract void mymethod();
}
public class Outer_class {
public static void main(String args[]) {
AnonymousInner inner = new AnonymousInner() {
public void mymethod() {
System.out.println("This is an example of anonymous inner class");
}
};
inner.mymethod();
}
}
So I am a bit lost how the second example is working.
It's because you're making an anonymous class - you're defining in place an implementation of your abstract class without a name, that can be used only here and then instantiating this (concrete) class. More about it here.
Other example would be using lambdas everywhere, where functional interface is needed, for example in streams:
stream.filter(a -> a.isTrue)...
// or
stream.filter(ClassA::isTrue)...
Here lambda and method reference are treated as implementations of Predicate.
Here, you are creating an object of the inner class that extends the abstract class. You can decompile the class file generated and see it for yourself.
This is the class that will be generated after the code compiles. (I've decompiled the class and it will look something like this :
final class Outer_class$1
extends AnonymousInner
{
public void mymethod()
{
System.out.println("This is an example of anonymous inner class");
}
}
You can clearly see that the inner class is providing an implementation for the abstract class.
I have below scenario :
class C {
static void m1() {}
}
interface I {
default void m1() {}
}
//this will give compilation error : inherited method from C cannot hide public abstract method in I
class Main extends C implements I {
}
Below are my questions:
I am aware that instance method will override the default methods but what if static methods in class have same signature as default method in Interface?
If static method m1() in class C would be public then compilation error will be :
static method m1() conflicts with abstract method in I.
so when the access modifier was default it was trying to hide and when it is public it is conflicting. why is this difference? what is the concept behind it?
Ultimately that boils down to the fact that when you have something like this:
class Me {
public static void go() {
System.out.println("going");
}
}
These both would be allowed:
Me.go();
Me meAgain = new Me();
meAgain.go(); // with a warning here
Intersting is that this would work too for example:
Me meAgain = null;
meAgain.go();
Personally I still see this as design flaw that could not be retracted due to compatibility - but I wish the compiler would not allow me to access the static method from an instance.
Your first question is not related to java-8 per-se, it has been like this before java-8:
interface ITest {
public void go();
}
class Test implements ITest {
public static void go() { // fails to compile
}
}
default methods just follow the same rule here. Why this happens is actually detailed quite a lot on stack overflow - but the underlying idea is that potentially this would cause confusion on which method to call (imagine ITest would be a class that Test would extends and you do ITest test = new Test(); test.go(); -> which method are you calling?)
I think that for the same reasons this is not allowed also (which is basically your second question, otherwise you would have a static and non-static method with the same signatures)
static class Me {
static void go() {
}
void go() {
}
}
It's interesting that this is sort of fixed (I guess that they realized it would be really bad to do the same mistake again) in method references:
static class Mapper {
static int increment(int x) {
return x + 1;
}
int decrement(int x) {
return x - 1;
}
}
Mapper m = new Mapper();
IntStream.of(1, 2, 3).map(m::increment); // will not compile
IntStream.of(1, 2, 3).map(m::decrement); // will compile
Answering your 1st question:
Both the "static method in class" and the "default method in interface" are available to the class Main, and hence if they have the same signature, it will create ambiguity.
For example:
class C{
static void m1(){System.out.println("m1 from C");}
}
public class Main extends C{
public static void main(String[] args) {
Main main=new Main();
main.m1();
}
}
Output: m1 from C
Similarly,
interface I{
default void m1(){System.out.println("m1 from I");}
}
public class Main implements I{
public static void main(String[] args) {
Main main=new Main();
main.m1();
}
}
Output: m1 from I
As you can see, both these can be accessed similarly. So this is also the reason for conflict when you implement I and extend C.
Answering your second question:
If your classed and interfaces are in the same package, the default and public access modifier should work similarly.
Also, m1() in C is static which cannot be overridden, and hence it cannot be considered as implementation of m1() in I and so the compilation issue.
Hope that helps!
I will answer your first question since the second is already answered
I am aware that instance method will override the default methods but
what if static methods in class have same signature as default method
in Interface?
I am assuming you are using JDK 1.8 and hence the confusion. default modifier in an interface method is not talking about its access specifications. Instead it mentions that the interface itself need to implement this method. Access specification for the method is still public. Starting from JDK8 , interfaces allow you specify methods with default modifer to allow to extend interfaces in a backward compatible way.
In your interface you had to give default void m1() {} for the compilation to be successfull. Normally we simply define them in an abstract way like void m1(); in an interface You had to implement the method because you specified the method as default. Hope you understand.
Because class methods in java can also be called using instance variables, this construct will lead to ambiguities:
Main m = new Main();
m.m1();
It is unclear if the last statement should call the class method C.m1() or the instance method I.m1().
I was learning through interfaces when I noticed that you can now define static and default methods in an interface.
public interface interfacesample2 {
public static void method() {
System.out.println("hello world");
}
public default void menthod3() {
System.out.println("default print");
}
}
Kindly explain the difference of the two and also if there's an example of when we would use this would be nice. A little confused on Interfaces.
Differences between static and default methods in Java 8:
1) Default methods can be overriden in implementing class, while static cannot.
2) Static method belongs only to Interface class, so you can only invoke static method on Interface class, not on class implementing this Interface, see:
public interface MyInterface {
default void defaultMethod(){
System.out.println("Default");
}
static void staticMethod(){
System.out.println("Static");
}
}
public class MyClass implements MyInterface {
public static void main(String[] args) {
MyClass.staticMethod(); //not valid - static method may be invoked on containing interface class only
MyInterface.staticMethod(); //valid
}
}
3) Both class and interface can have static methods with same names, and neither overrides other!
public class MyClass implements MyInterface {
public static void main(String[] args) {
//both are valid and have different behaviour
MyClass.staticMethod();
MyInterface.staticMethod();
}
static void staticMethod(){
System.out.println("another static..");
}
}
A static method is a method that applies to the class 'namespace', so to speak. So a static method foo of interface Interface is accessed by Interface.foo(). Note that the function call does not apply to any particular instance of the interface.
A default implementation bar on the other hand, is called by
Interface x = new ConcreteClass();
x.bar();
A static interface method cannot know about the this variable, but a default implementation can.
1. explain the difference of the two
Static interface methods are like static class methods(here they belong to Interface only). Where as the default interface methods provide default implementation of interface methods (which implementing classes may override)
But remember in case a class is implementing more than one interface with same default method signature then the implementing class needs to override the default method
You can find a simple example below (can DIY for different cases)
public class Test {
public static void main(String[] args) {
// Accessing the static member
I1.hello();
// Anonymous class Not overriding the default method
I1 t = new I1() {
#Override
public void test() {
System.out.println("Anonymous test");
}
};
t.test();
t.hello("uvw");
// Referring to class instance with overridden default method
I1 t1 = new Test2();
t1.test();
t1.hello("xyz");
}
}
interface I1 {
void test();
//static method
static void hello() {
System.out.println("hello from Interface I1");
}
// default need not to be implemented by implementing class
default void hello(String name) {
System.out.println("Hello " + name);
}
}
class Test2 implements I1 {
#Override
public void test() {
System.out.println("testing 1234...");
}
#Override
public void hello(String name) {
System.out.println("bonjour" + name);
}
}
2. when we would use this would be nice.
That depends on your problem statement. I would say Default methods are useful, if you need same implementation for a method in your specification in all the classes in that contract, Or it may be used like Adapter classes.
here is a good read: https://softwareengineering.stackexchange.com/questions/233053/why-were-default-and-static-methods-added-to-interfaces-in-java-8-when-we-alread
also below oracle doc explains default & static methods for evolving existing interfaces:
Users who have classes that implement interfaces enhanced with new
default or static methods do not have to modify or recompile them to
accommodate the additional methods.
http://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html
Here is my view:
static method in interface:
You can call it directly (InterfacetA.staticMethod())
Sub-class will not be able to override.
Sub-class may have method with same name as staticMethod
default method in interface:
You can not call it directly.
Sub-class will be able to override it
Advantage:
static Method: You don't need to create separate class for utility method.
default Method: Provide the common functionality in default method.
This link has some useful insights, have listed few of them here.
default & static methods have bridged down the differences between interfaces and abstract classes.
Interface default methods:
It helps in avoiding utility classes, such as all the Collections class method can be provided in the interfaces itself.
It helps in extending interfaces without having the fear of breaking implementation classes.
Interface static methods:
They are part of interface, we can’t use it for implementation class objects.
It helps in providing security by not allowing implementation classes to override them.
Like to quote another useful reference.
As per Java14 JLS doc:
Default Method:
It is an instance method declared in an interface with the default
modifier
It can be accessed only by the instance of the implementing class
only
Its body is always represented by a block, which provides a default
implementation or behaviour for any implementing class without
overriding the method
It can never be static or private
Static Method:
It can be invoked by interface without reference to a particular
object, just like class static methods
Static method can be private
The implementing class can not access static method
Lets understand it with the help of below example code:
public interface MyInterface {
private void privateMethod() {
System.out.println("Hi, this is privateMethod");
}
private static void staticPrivateMethod() {
System.out.println("Hi, this is staticPrivateMethod");
}
static void staticMethod() {
//privateMethod(); // Non-static method cannot be referenced from a static contex
System.out.println("Hi, this is staticMethod");
staticPrivateMethod();
}
default void defaultMethod() {
System.out.println("Hi, this is defaultMethod");
}
}
public class MyInterfaceImpl implements MyInterface{
public static void main(String[] args) {
MyInterface.staticMethod();
// myInterface.staticMethod(); // Not allowed
MyInterface myInterface = new MyInterfaceImpl();
myInterface.defaultMethod();
// MyInterface.defaultMethod(); // Not allowed
}
}
According to Oracle's Javadocs: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.
A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.
Normally, static method in interface is used as Helper methods while default method are used as a default implementation for classes that implements that interface.
Example:
interface IDemo {
//this method can be called directly from anywhere this interface is visible
static int convertStrToInt(String numStr) {
return Integer.parseInt(numStr);
}
//getNum will be implemented in a class
int getNum();
default String numAsStr() {
//this.getNum will call the class's implementation
return Integer.toString(this.getNum());
}
}
Interface default methods:
It helps in avoiding utility classes, such as all the Collections class method can be provided in the interfaces itself.
It helps in extending interfaces without having the fear of breaking implementation classes.
Interface static methods:
They are part of interface, we can’t use it for implementation class objects.
It helps in providing security by not allowing implementation classes to override them.
Now how static method providing security. Let's see an example.
interface MyInterface {
/*
* This is a default method so we need not to implement this method in the implementation classes
*/
default void newMethod() {
System.out.println("Newly added default method in Interface");
}
/*
* This is a static method. Static method in interface is similar to default method except that we cannot override them in the implementation classes. Similar to default methods, we need to implement these methods in implementation classes so we can safely add them to the existing interfaces.
*/
static void anotherNewMethod() {
System.out.println("Newly added static method in Interface");
}
/*
* Already existing public and abstract method We must need to implement this method in implementation classes.
*/
void existingMethod(String str);
}
public class Example implements MyInterface {
// implementing abstract method
public void existingMethod(String str) {
System.out.println("String is: " + str);
}
public void newMethod() {
System.out.println("Newly added default method in Class");
}
static void anotherNewMethod() {
System.out.println("Newly added static method in Class");
}
public static void main(String[] args) {
Example obj = new Example();
// calling the default method of class
obj.newMethod();
// calling the static method of class
obj.anotherNewMethod();
// calling the static method of interface
MyInterface.anotherNewMethod();
// calling the abstract method of interface
obj.existingMethod("Java 8 is easy to learn");
}
}
Here obj.newMethod(); printing class implementation logic, means we can change the logic of that method inside implementation class.
But obj.anotherNewMethod(); printing class implementation logic ,but not changed interface implementation. So if any encryption-decryption logic written inside that method you can't change.
we cannot execute Interfacesample2.menthod3(); because it is not static method. In order to execute method3() we need an instance of Interfacesample2 interface.
Please find the following practical example:
public class Java8Tester {
public static void main(String args[]){
// Interfacesample2.menthod3(); Cannot make a static reference to the non-static method menthod3 from the type Interfacesample2
new Interfacesample2(){ }.menthod3();// so in order to call default method we need an instance of interface
Interfacesample2.method(); // it
}
}
interface Interfacesample2 {
public static void method() {
System.out.println("hello world");
}
public default void menthod3() {
System.out.println("default print");
}
}
Starting Java 8 interface can also have static method. Like static method of a class, static method of an interface can be called using Interface name.
Example
public interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
default int multiply(int a, int b) {
throw new RuntimeException("Operation not supported. Upgrade to UltimateCalculator");
}
static void display(String value) {
System.out.println(value);
}
}
Difference between static and default method of interface is default method supports inheritance but static method does not. Default method can be overridden in inheriting interface.
Here is good read about interface default method and static method. Interface Default Method in Java 8
All good answers here. I would like to add another practical usage of the static function in the interface. The tip is coming from the book - Effective Java, 3rd Edition by Joshua Bloch in Chapter2: Creating and Destroying Object.
Static functions can be used for static factory methods.
Static factory method are methods which return an object. They work like constructor. In specific cases, static factory method provides more readable code than using constructor.
Quoting from the book - Effective Java, 3rd Edition by Joshua Bloch
Prior to Java 8, interfaces couldn’t have static methods. By
convention, static factory methods for an interface named Type were
put in a noninstantiable companion class (Item 4) named Types.
Author gives an example of Collections where such static factory method is implemented. Checking on the code, Josh Bloch can be seen as first author of Collections class. Although Collections is a class and not interface. But the concept still applies.
For example, the Java Collections Framework has forty-five utility
implementations of its interfaces, providing unmodifiable collections,
synchronized collections, and the like. Nearly all of these
implementations are exported via static factory methods in one
noninstantiable class (java.util.Collections). The classes of the
returned objects are all nonpublic.
Further he explains that API is not only smaller, it helps with the code readability and API ease..
It is not just the bulk of the API that is reduced but the conceptual
weight: the number and difficulty of the concepts that programmers
must master in order to use the API. The programmer knows that the
returned object has precisely the API specified by its interface, so
there is no need to read additional class documentation for the
implementation class.
Here is one of the static method from java.util.Collections class:
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
return new UnmodifiableCollection<>(c);
}
Static Interface Method:
It is a static method which belongs to the interface only. We can
write implementation of this method in interface itself.
Static method can invoke only on interface class not on class.
Interface and implementing class , both can have static method with the same name without overriding each other.
It can be used as a utility method
Default Method:
It is a method with default keyword and class can override this method.
It can be invoked on interface as well as class.
We can override the default method in implementing class.
It can be used to provide common functionality in all implementing classes.
There is a link with detailed explanation. For detailed example: Default method vs static method in an interface in Java?
I have two different interfaces which employ the same methods but dont implement or extend each other. These two interfaces are each extended by another class which implements the interfaces methods
I then have a class which is located in a seperate package which calls the interface methods.
So the class has methods which calls the methods of the interfaces, which are all the same.
public void doThis(){
connection.doThis();
}
public void doThat(){
connection.doThat();
}
public void doAnother(){
connection.doAnother();
}
Now, i want to make the variable connection work for both interface1 and interface2.
My idea was to set connection as a class variable
Object connection
and then to change it type to interface1 or interface2 depending on a condition:
if(this){
//condition which converts connection to type interface1
}
else{
//condition which converts connection to type interface2
}
How do i do this. Can i do this?
I have been given an interface which can not be changed, yet does not implement remote. But my project uses RMI. So i created a 2nd interface in a seperate package which implemets Remote. Thus the reason for 2 different interfaces that do he same thing.
I think it would be easier to make the class containing the method 'connection' public, as it would be accessible from all packages.
This seems like a really weird setup, but I won't question you.
If you know the condition at the method call site (eg, the condition is a constant flag passed to the method), you could parameterize the method with a generic instead. For example:
public class TestGenerics {
public static interface A {
public void a();
}
public static interface B {
public void a();
}
public static class C implements A, B {
public void a() {
System.out.println("a");
}
}
public static <T> T getCAsT() {
return (T) new C();
}
public static void main(String[] args) {
A a = TestGenerics.<A>getCAsT();
B b = TestGenerics.<B>getCAsT();
a.a();
b.a();
}
}
Otherwise, I would try to merge the two interfaces in some way.
I have a Java problem with nested classes.
My first class structure looked like this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private interface NestedClass {
public void method();
}
private class NestedClass1 {
public void method() {
}
}
private class NestedClass2 {
public void method(){
}
}
}
But now I want these method() methods to be static because they should be principally.
I cannot make them static without having them in a static class, but that's no problem, I made the classes static, they should be anyway.
It looks like this right now:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static interface NestedClass {
public void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But then the trouble begins. A static method does not inherit correctly from a non-static interface method, as I get this message This static method cannot hide the instance method from TopClass.NestedClass in Eclipse.
When I make the interface method static, it gives me this error: Illegal modifier for the interface method method; only public & abstract are permitted
So I thought of an abstract class, and tried this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static abstract class NestedClass {
public static abstract void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But again, seemingly abstract methods cannot be declared static: The abstract method method in type NestedClass can only set a visibility modifier, one of public or protected.
Leaving the static away (in the abstract class method), errors this on the method methods in the NestedClass1 & 2: This static method cannot hide the instance method from TopClass.NestedClass.
Isn't there any way to declare some kind of superstructure for covering static methods?
EDIT:
The problem I actually try to solve it the lack of possibility of Java for storing references to methods. So instead I have those classes everyone with just one method, but to store them in a List f.e. they must be able to be "caught" by a superstructure.
I got the hint to try anonymous classes or enums, gonna try that now.
Interfaces and statics don't go together. At all. There is no Java support for creating / imposing patterns on static methods.
A static method declaration must always be followed by a definition. It cannot be implemented by subclasses.
I think you're just not approaching your problem right. Try a different approach!
Make NestedClass an interface NestedInterface and store your different implementations as anonymous classes implementing this interface:
public static final NestedInterface firstNested = new NestedInterface() {
#Override
public void method() {
// ...
}
};
Make NestedClass an enumeration NestedEnum and store your different implementations as enumeration values implementing an abstract method from the enumeration. This only works if you have a fixed number of implementations you which to choose from and you do not want to accept NestedClass implementations from outside sources.
public enum NestedEnum {
FIRST {
#Override
public void method() {
// ...
}
};
public abstract void method();
}
EDIT: In reply to your comment:
The classes itself are static as well..
static in the context of a nested class means that this class can be instantiated without an instance of the containing class.
A regular nested class such as in your first example can be instantiated through TopClass.this.new NestedClass1(). Normally you'd simply write new NestedClass1() from within the constructor or an instance method of TopClass, but in this verbose form you can clearly see the dependence on TopClass.this. This can also be seen from any method of NestedClass1, as you have access to the containing class with TopClass.this.
A static nested class such as in your second example can be instantiated through new TopClass.NestedClass1(). Once again, you could just write new NestedClass1() but the verbose form clearly shows that the construction only depends on TopClass and is not associated with an instance of TopClass. You could even create an instance from an outside class using the same snippet new TopClass.NestedClass1() without ever creating a TopClass instance.
I suggest you take a look at this question on inner classes and static nested classes.
The fact the your interface/abstract class is nested is irrelevant to the problem.
You just can't. There is no way in Java to enforce some class to implement static methods. Just cry and surrender and use instance methods.
static abstract is a contradiction. Static methods are not like other languages' class methods. When you make a static method it goes on a single class, it doesn't get inherited by or have its implementation deferred to subclasses.
You don't explain why you want these methods to be static. If you want these methods to be defined by subclasses then they shouldn't be.