Java приведение интерфейса к классу - PullRequest
4 голосов
/ 24 октября 2011

У меня есть вопрос об интерфейсе и реализации интерфейса класса.

Это мой код:

interface iMyInterface {
    public iMethod1();
}

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

Я хотел бы создать экземпляр iMyInterface следующим образом:

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

Это нормально, но как я могу вызвать iMethod2() из моего экземпляра интерфейса?Работает ли это и безопасно:

((cMyClass)i).iMethod2();

Спасибо за помощь.

Ответы [ 3 ]

11 голосов
/ 24 октября 2011

Да, это будет работать (если вы измените объявление cMyClass для реализации iMyInterface), и это безопасно, если ссылка действительно ссылается на экземпляр cMyClass.

Однако это вообще плохая идея. Весь смысл использования интерфейса в том, чтобы иметь возможность работать с любой реализацией - это отделять абстракцию от реализации. Если затем вам потребуется конкретная реализация, вы можете также сделать тип i просто cMyClass для начала.

Итак, предположим, что вместо того, чтобы вызывать конструктор cMyClass самостоятельно, вы получите параметр метода типа iMyInterface - плохая идея привести к cMyClass в этот момент, так как это может быть другой реализация интерфейса.

(С другой стороны, неплохо бы начать следовать соглашениям об именах Java, в которых говорится, что классы и интерфейсы должны быть в Pascal-регистре, поэтому не используйте префиксы c и i.)

0 голосов
/ 10 марта 2018

Существует еще одна альтернатива приведения Interface к классу.Вот пример как.

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;
}
}

А чтобы получить значения из вашего интерфейса, вот пример кода.

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

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

Вывод:

Печать из cMyClass iMethod1 ()

Печать из cMyClass iMethod2 ()

Я думаю, что это хороший пример того, как выможет отделить код интерфейса от кода класса.Просто создайте экземпляр интерфейса и используйте каждый метод через геттер с этим интерфейсом.

0 голосов
/ 24 октября 2011

Это будет работать (при условии, что cMyClass реализует iMyInterface и вы находитесь в области действия модификатора protected ), но это не является правильным подходом OO.

Если вы хотите использовать iMethod2, подумайте:

  • добавьте его в интерфейс
  • создайте другой интерфейс, содержащий этот метод
  • Используйте cMyClass myClass = new cMyClass();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...