Inner class within Interface
Asked Answered
I

13

118

Is it possible to create an inner class within an interface?
If it is possible why would we want to create an inner class like that since we are not going to create any interface objects?

Do these inner classes help in any development process?

Irreplaceable answered 8/3, 2010 at 11:12 Comment(0)
R
60

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...).

Reverend answered 8/3, 2010 at 11:21 Comment(6)
Can you add some examples of usage? I've tested something similar some time ago and haven't understood what can I gain from using this construction.Pennyroyal
@Roman: well I remember I've encountered this on some project (relatively clean project would I add but they weren't mine) but I don't know if it's really clean or not. I've added a tiny example that looks like what I've seen but once again: this wasn't my code and I'm not using that construct so I'm not the most qualified to come up with valid examples :) IIRC the class inside was always named, for example StateChecker and calls would always look like: A.StateChecker.check( a ) or something like that.Reverend
If you say that “there's no such thing as an "static inner class"” your answer that “you can create both a nested class or an inner class inside a Java interface” is fundamentally wrong. Using your narrowed definition, interfaces can not have inner classes. You can omit the static modifier of an interface’s nested class but still, it’s a nested class, not an inner class.Ghat
This answer is wrong. Interfaces can have static nested classes but not inner classes.Digraph
@PaulBoddington You're right. Even removing 'static', the B class is a static nested class and not an inner class; interfaces get special treatment. I couldn't find mention of this online, except for in the spec itself: "A member class of an interface is implicitly static so is never considered to be an inner class." docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3Lustre
I used this pattern for a @FeignClient for OpenFeign because it doesn't support parametrized types so I created a base class type instead.Dimitry
G
121

Yes, we can have classes inside interfaces. One example of usage could be

public interface Input
{
    public static class KeyEvent {
         public static final int KEY_DOWN = 0;
         public static final int KEY_UP = 1;
         public int type;
         public int keyCode;
         public char keyChar;
    }
    public static class TouchEvent {
         public static final int TOUCH_DOWN = 0;
         public static final int TOUCH_UP = 1;
         public static final int TOUCH_DRAGGED = 2;
         public int type;
         public int x, y;
         public int pointer;
    }
    public boolean isKeyPressed(int keyCode);
    public boolean isTouchDown(int pointer);
    public int getTouchX(int pointer);
    public int getTouchY(int pointer);
    public float getAccelX();
    public float getAccelY();
    public float getAccelZ();
    public List<KeyEvent> getKeyEvents();
    public List<TouchEvent> getTouchEvents();
}

Here the code has two nested classes which are for encapsulating information about event objects which are later used in method definitions like getKeyEvents(). Having them inside the Input interface improves cohesion.

Grapevine answered 10/12, 2013 at 12:41 Comment(2)
@Levit Just wondering, how the implemented class will look like?Revell
Would love to see an implementation in action for the above usage. Thank you.Amboceptor
R
60

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...).

Reverend answered 8/3, 2010 at 11:21 Comment(6)
Can you add some examples of usage? I've tested something similar some time ago and haven't understood what can I gain from using this construction.Pennyroyal
@Roman: well I remember I've encountered this on some project (relatively clean project would I add but they weren't mine) but I don't know if it's really clean or not. I've added a tiny example that looks like what I've seen but once again: this wasn't my code and I'm not using that construct so I'm not the most qualified to come up with valid examples :) IIRC the class inside was always named, for example StateChecker and calls would always look like: A.StateChecker.check( a ) or something like that.Reverend
If you say that “there's no such thing as an "static inner class"” your answer that “you can create both a nested class or an inner class inside a Java interface” is fundamentally wrong. Using your narrowed definition, interfaces can not have inner classes. You can omit the static modifier of an interface’s nested class but still, it’s a nested class, not an inner class.Ghat
This answer is wrong. Interfaces can have static nested classes but not inner classes.Digraph
@PaulBoddington You're right. Even removing 'static', the B class is a static nested class and not an inner class; interfaces get special treatment. I couldn't find mention of this online, except for in the spec itself: "A member class of an interface is implicitly static so is never considered to be an inner class." docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3Lustre
I used this pattern for a @FeignClient for OpenFeign because it doesn't support parametrized types so I created a base class type instead.Dimitry
S
49

A valid use, IMHO, is defining objects that are received or returned by the enclosing interface methods. Tipically data holding structures. In that way, if the object is only used for that interface, you have things in a more cohesive way.

By example:

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

But anyway... it's only a matter of taste.

Similarity answered 7/5, 2012 at 11:47 Comment(0)
S
47

Quote from the Java 7 spec:

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.

It is NOT possible to declare non-static classes inside a Java interface, which makes sense to me.

Summit answered 16/10, 2014 at 11:41 Comment(3)
Thank you. This is probably the most concise answer of all.Vereeniging
This is the answer that I was looking for.. but the OP asks several questions.. anyway have my updoot.Kebab
key is "inner class is implicitly static and public"Guenther
O
12

An interesting use case is to provide sort of a default implementation to interface methods through an inner class as described here: https://mcmap.net/q/188933/-java-interface-implementation-pair-closed (to overcome the problem of single-class-inheritance).

Objurgate answered 13/2, 2013 at 10:43 Comment(1)
And this is exactly why private member classes would make sense.Inefficiency
T
10

Yes it is possible to have static class definitions inside an interface, but maybe the most useful aspect of this feature is when using enum types (which are special kind of static classes). For example you can have something like this:

public interface User {
    public enum Role {
        ADMIN("administrator"),
        EDITOR("editor"),
        VANILLA("regular user");

        private String description;

        private Role(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    public String getName();
    public void setName(String name);
    public Role getRole();
    public void setRole(Role role);
    ...
}
Timehonored answered 8/4, 2015 at 0:42 Comment(0)
P
8

It certainly is possible, and one case where I've found it useful is when an interface has to throw custom exceptions. You the keep the exceptions with their associated interface, which I think is often neater than littering your source tree with heaps of trivial exception files.

interface MyInterface {

   public static class MyInterfaceException extends Exception {
   }

   void doSomething() throws MyInterfaceException;
}
Paraglider answered 14/11, 2014 at 3:59 Comment(0)
M
1

What @Bachi mentions is similar to traits in Scala and are actually implemented using a nested class inside an interface. This can be simulated in Java. See also java traits or mixins pattern?

Mani answered 2/5, 2013 at 12:48 Comment(0)
T
1

You can also create "Helper" static classes for common functionality for the objects that implement this interface:

public interface A {
    static class Helper {
        public static void commonlyUsedMethod( A a ) {
           ...
        }
    }
}
Tamratamsky answered 20/10, 2016 at 19:21 Comment(0)
M
1

Maybe when you want more complex constructions like some different implementation behaviours, consider:

public interface A {
    public void foo();

    public static class B implements A {
        @Override
        public void foo() {
            System.out.println("B foo");
        }
    }
}

This is your interface and this will be the implementee:

public class C implements A {
    @Override
    public void foo() {
        A.B b = new A.B();
        b.foo(); 
    }

    public static void main(String[] strings) {
        C c = new C();
        c.foo();
    }
}

May provide some static implementations, but won't that be confusing, I don't know.

Maelstrom answered 20/10, 2016 at 19:43 Comment(0)
O
0

I found a use fir this type of construct.

  1. You can use this construct to defines and group all the static final constants.
  2. Since, it is an interface you can implement this on an class.

You have access to all the constants grouped; name of the class acts as a namespace in this case.

Ovotestis answered 2/6, 2016 at 18:7 Comment(0)
D
0

I'm needing one right now. I have an interface where it would be convenient to return a unique class from several of it's methods. This class only makes sense as a container for responses from methods of this interface.

Hence, it would be convenient to have a static nested class definition, which is associated only with this interface, since this interface should be the only place where this results container class is ever created.

Dylan answered 13/6, 2017 at 22:3 Comment(0)
E
0

For instance traits (smth like interface with implemented methods) in Groovy. They are compiled to an interface which contains inner class where all methods are implemented.

Emersen answered 13/6, 2017 at 22:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.