Use of Static Interface Inside of Java Class [duplicate] - java

This question already has answers here:
What is a static interface in java?
(3 answers)
Closed 3 years ago.
Below class is a java class where i have seen static interface Inside this class what is the use of this static interface i have never seen and what advantages to create interface like this
public class Validator {
public static interface ItemValidator {
public int withinTolerance(Number value, Number oldValue);
}
}

An interface which is declared inside another interface or class is called nested interface. They are also known as inner interface. Since nested interface cannot be accessed directly, the main purpose of using them is to resolve the namespace by grouping related interfaces (or related interface and class) together. This way, we can only call the nested interface by using outer class or outer interface name followed by dot( . ), followed by the interface name.
Example: Entry interface inside Map interface is nested. Thus we access it by calling Map.Entry.
Note:
Nested interfaces are static by default. You don’t have to mark them static explicitly as it would be redundant.
Nested interfaces declared inside class can take any access modifier, however nested interface declared inside interface is public implicitly.
Example 1: Nested interface declared inside another interface
interface MyInterfaceA{
void display();
interface MyInterfaceB{
void myMethod();
}
}
class NestedInterfaceDemo1
implements MyInterfaceA.MyInterfaceB{
public void myMethod(){
System.out.println("Nested interface method");
}
public static void main(String args[]){
MyInterfaceA.MyInterfaceB obj=
new NestedInterfaceDemo1();
obj.myMethod();
}
}

Related

Instantiation of abstract classes [duplicate]

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.

How interfaces create objects when using at anonymous inner classes [duplicate]

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.

Can I make a static factory method in an abstract class? [duplicate]

This question already has answers here:
Can we use static method in an abstract class?
(5 answers)
Closed 5 years ago.
I am making a chess game and trying to figure out if there is a way to make my abstract class "Piece" have a method that returns a new instance of the concrete implementations like Pawn or Rook.
For example:
static public Piece newNorthPiece(){
return new Piece(true);
}
Except instead of returning a Piece I want it to return whatever the class that called the method is. So if I call Pawn.newNorthPiece() I want it to return to me a new Pawn(true).
And I would like to do this without having to write a new factory method for every class that extends the Piece class.
Can I make a static factory method in an abstract class?
Yes, you can create a static method inside abstract class and the method will look the below:
public abstract class PieceFactory {
public static Piece getPiece(String pieceType){
switch(pieceType) {
case NorthPiece:
return new NorthPiece();
case Pawn:
return new Pawn();
}
}
}
And you can call the PieceFactory.getPiece("Pawn") whichn returns the instance of Pawn.
In Java, you can't do that as super class does not know how many classes are extending it. The closest you can get to it is by implementing the method like this:
class Piece {
public static Piece getInstance(Class<? extends Piece> clazz) throws InstantiationException, IllegalAccessException{
return clazz.newInstance();
}
}
class Pawn extends Piece {
}
You can then call the method and pass Piece's class like this:
Piece piece = Piece.getInstance(Pawn.class);
This will give you the instance of Pawn class, you can use it to get the instance of any other class that extends Piece.
P.S. This depends on a couple of factors (e.g. child class having a public constructor, Piece class having access to child class etc)
The Piece class is abstract, so you cannot instantiate it. You need to have a concrete implementation of your Piece class.

Where it is useful to have nested classes in an interface? [duplicate]

This question already has answers here:
Inner class within Interface
(13 answers)
Closed 7 years ago.
In which scenario can an interface have nested classes?
The following code is allowed and valid.
public interface Iface {
void show();
class ifaceClass {
int x;
public ifaceClass() {
System.out.println(x);
}
}
}
I am also struggling to make object of class ifaceClass.
EDIT :
I am able to make object like this
public class Test implements Iface {
public static void main(String[] args){
ifaceClass ifaceClassObj = new ifaceClass();
}
public void show() {
}
}
I noticed if Test has not implemented the Iface then I needed following import,
import com.jls.Iface.ifaceClass;
But it boiled down to same problem that why not use it as a just another class.
What the difference or value addition with this approach ?
You can create an instance of ifaceClass inside the class that implements Iface:
interface Iface {
void show();
class ifaceClass {
int x;
public ifaceClass() {
System.out.println(x);
}
}
}
public class Test implements Iface {
public static void main(String args[]) {
ifaceClass iface = new ifaceClass();
}
#Override
public void show() {
// ...
}
}
If the class doesn't implement the interface, just create an instance like this:
Iface.ifaceClass iface = new Iface.ifaceClass();
Why create a class inside an interface? Basically for the same reason you create a class inside another class, to group related classes together.
Where it is useful to have nested classes in an interface?
There is no such case which can only be fulfilled with inner class of interface. It is syntactically valid to have inner class in interface and for the class which implement interface can create instance of class and apart from that Interface.Class can also make that class accessible because it can not be private at all.
I noticed if Test has not implemented the Iface then I needed
following import import com.jls.Iface.ifaceClass;
Not necessarily, if your interface is accessible your inner class will automatically become accessible.Here you are trying to access class directly without even importing interface in that case following statement need above import statement.
ifaceClass ifaceClassObj = new ifaceClass();
But it boiled down to same problem that why not use it as a just
another class. What the difference or value addition with this
approach
Exactly, creating another class can also provide you the same facility and I have never seen any use case in my day to day programming which can only be fulfilled with inner class of interface.It does not provide anything else than accessibility through the interface.
I have used it once which I think quite a bad practice though. One day we need to implement one common method in different classes which are implementing interface say X and we wanted to add one extra method to be used by all this classes to add one kind of check on the Object which only check some parameter and return boolean even though that use case can be fulfilled in other way but to be specific that it is only intended for classes which are implementing this interface we have added class in interface so that we can provide that method to implementing classes.(NOTE : Nowadays default method can be used in this case instead of inner class)
Here, it is wise to note that in huge projects it is quite impossible for anyone ( other than creator ) to note that any interface has inner class. So, until we implement that class or manually check the interface we can not came to know that interface has inner class.

How to define nested static classes with static methods, inherited from a nested interface in Java?

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.

Categories