Inner Class Within Interface

Inner class within Interface

Yes, you can create both a nested class or an inner class inside a Java interface (note that contrarily to popular belief there's no such thing as an "static inner class": this simply makes no sense, there's nothing "inner" and no "outter" class when a nested class is static, so it cannot be "static inner").

Anyway, the following compiles fine:

public interface A {
class B {
}
}

I've seen it used to put some kind of "contract checker" directly in the interface definition (well, in the class nested in the interface, that can have static methods, contrarily to the interface itself, which can't). Looking like this if I recall correctly.

public interface A {
static class B {
public static boolean verifyState( A a ) {
return (true if object implementing class A looks to be in a valid state)
}
}
}

Note that I'm not commenting on the usefulness of such a thing, I'm simply answering your question: it can be done and this is one kind of use I've seen made of it.

Now I won't comment on the usefulness of such a construct and from I've seen: I've seen it, but it's not a very common construct.

200KLOC codebase here where this happens exactly zero time (but then we've got a lot of other things that we consider bad practices that happen exactly zero time too that other people would find perfectly normal so...).

Inner class within Interface in C#

Simply put no you can't have a class inside an interface.

From your comments you are talking about having a restricted list of available strings for the keys so I'm wondering if you are in fact not looking for a string/string lookup but just want a convenient way of referencing a list of fixed strings. So a class with constants is all you need:

public static class Strings 
{
public const string AString = "A";
public const string BString = "B";
public const string CString = "C";
}

Accessed like this:

var s = Strings.AString;

Inner class in interface vs in class

Static inner classes are mostly similar to top-level classes, except the inner class has access to all the static variables and methods of the enclosing class. The enclosing class name is effectively appended to the package namespace of the inner class. By declaring a class as a static inner class, you are communicating that the class is somehow inseparably tied to the context of the enclosing class.

Non-static inner classes are less common. The main difference is that instances of a non-static inner class contain an implicit reference to an instance of the enclosing class, and as a result have access to instance variables and methods of that enclosing class instance. This leads to some odd looking instantiation idioms, for example:

Levels levels = new Levels(); // first need an instance of the enclosing class

// The items object contains an implicit reference to the levels object
Levels.Items items = levels.new Items();

Non-static inner classes are much more intimately tied to their enclosing classes than static inner classes. They have valid uses (for example iterators are often implemented as non-static inner classes within the class of the data structure they iterate over).

It's a common mistake to declare a non-static inner class when you only really need the static inner class behaviour.

Inner classes inside Interface

You can define a class inside an interface. Inside the interface, the inner class is implicitly public static.

From JLS Section 9.1.4:

The body of an interface may declare members of the interface, that is, fields (§9.3), methods (§9.4), classes (§9.5), and interfaces (§9.5).

From JLS Section 9.5:

Interfaces may contain member type declarations (§8.5).

A member type declaration in an interface is implicitly static and public. It is permitted to redundantly specify either or both of these modifiers.

The only restriction on the inner class defined inside the interface or any other class, for that matter, is that, you have to access them using the enclosing member name.

Apart from that, there is no relation between them. The inner class will result in completely a different class file after compilation.

For e.g., if you compile the following source file:

interface Hello {
class HelloInner {

}
}

Two class files will be generated:

Hello.class
Hello$HelloInner.class

Are nested classes inside an interface implicitly static and final?

Lets find out. Lets create structure like:

interface Interface{
class Foo{}
}

Now we can test:

System.out.println("static: " + Modifier.isStatic(Interface.Foo.class.getModifiers()));
System.out.println("final: " + Modifier.isFinal(Interface.Foo.class.getModifiers()));

which prints:

static: true
final: false

So nested classes are implicitly static, but not final.

We can confirm it also by adding class Bar extends Foo{} to our interface. final classes can't be extended but since such code compiles fine it means Foo is not final.

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

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.

Does a class inherit an abstract inner class declared within an interface when the class implements that interface?

A member class defined inside an interface is always implicitly static. It's not an inner class, but a static member class, and it doesn't have an outer class instance associated with it.

The Java Language Specification states this in section 9.5:

A member type declaration in an interface is implicitly public and
static. It is permitted to redundantly specify either or both of these
modifiers.

Hence, in your program 2, inside the constructor of class Outer2, you cannot say new J().super();, because Outer2 doesn't have an outer instance - it is not an inner class. The error from javac says as much: "illegal qualifier; Inner is not an inner class"



Related Topics



Leave a reply



Submit