13

I have a question about interface and class implementing interface.

This is my code:

interface iMyInterface {
    public iMethod1();
}

public class cMyClass implements iMyInterface {
    public iMethod1() {
        // some code
    }
    protected iMethod2() {
        // some code
    }
}

I would like to create an instance of iMyInterface as this :

iMyInterface i = new cMyClass();
i.iMethod1();

It's ok, but how can I call iMethod2() from my interface instance? Is this working and safe:

((cMyClass)i).iMethod2();

Thanks for help.

0

3 Answers 3

19

Yes, that will work (if you change the declaration of cMyClass to implement iMyInterface) and it's safe so long as the reference really does refer to an instance of cMyClass.

However, it's a generally bad idea. The whole point of using an interface is to be able to work with any implementation - it's to separate the abstraction from the implementation. If you're then going to require a specific implementation, you might as well make the type of i just cMyClass to start with.

So suppose instead of calling the cMyClass constructor yourself, you receive a method parameter of type iMyInterface - it's a bad idea to cast to cMyClass at that point, as it could be a different implementation of the interface.

(On a separate note, it's a good idea to start following Java naming conventions, which state that classes and interfaces should be Pascal-cased - so ditch the c and i prefixes.)

Sign up to request clarification or add additional context in comments.

3 Comments

I think that, if he's going to cast, he should verify the cast with instanceof, to be on the safe side.
@S.L.Barth: Unless the desired failure mode is an ClassCastException anyway, of course, in which case an unconditional cast is fine.
@Jon Skeet Thanks, I'm using it now including Method2 in interface. Sorry I forgot to add implements iMyInterface in my sample.
0

It will work (provided that cMyClass implements iMyInterface and you are in scope of protected modifier) but that is not the correct OO approch.

If you want to use iMethod2 consider:

  • adding it to the interface
  • create another interface containing that method
  • Use cMyClass myClass = new cMyClass();

2 Comments

Thanks, I add Method2 in my interface.
You actually want to restrict your instance type to the smallest reasonable interface like List<String> l = new ArrayList<>() ; if you want to use arraylist specific methods Widen your variable type.
0

There is some another alternative to cast Interface to a class. Here is example how.

interface iMyInterface {
   void iMethod1();
}

public class cMyClass implements iMyInterface {

private iMyInterface myInterface;

public cMyClass() {
    myInterface = this;
}

public void iMethod1(){
    System.out.println("Print from cMyClass iMethod1()");
}

protected void iMethod2() {
    System.out.println("Print from cMyClass iMethod2()");
}

/**
 * Getter so we can access to the interface methods.
 * @return
 */
public iMyInterface getMyInterface() {
    return myInterface;
}
}

And to get values from your interface, here is the code example.

public class Main {
public static void main(String[] args) {

    cMyClass myClass = new cMyClass();
    myClass.getMyInterface().iMethod1();
    myClass.iMethod2();
}
}

Output:

Print from cMyClass iMethod1()

Print from cMyClass iMethod2()

I think this is a good example how you can separate interface code from the class code. Just create instance of the interface and every method use through getter with that interface.

1 Comment

I know 4 years. But your answer does nothing. Calling the interface methods on the class itself is fine. There is no convention I know that tells you to separate them. And if you really want to you can cast implicitly : iMyInterface i = classInstance; you need no method for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.