Преобразование из экземпляра в интерфейс запрещено? - PullRequest
0 голосов
/ 11 февраля 2012

Очень простой код для теста:

interface Base {
    void interfaceTest();
    static final String m = "1";
}

interface Child extends Base {
    void interfaceTestChild();
}

class BaseClass implements Base {
    @Override
    public void interfaceTest() {
        System.out.println("BaseClassInterfaceTest");
    }
}

class ChildClass implements Child {

    @Override
    public void interfaceTest() {
        System.out.println("ChildClassInterfaceTest");
    }

    @Override
    public void interfaceTestChild() {
        System.out.println("interfaceTestChild");

    }
}

public class Src {
    public Child testFunc() {
        Base x = new BaseClass();
        return (Child)x;      <==Here got an "ClassCastException"
    }

    public static void main(String args[]) {
        Src testSrcInstance = new Src();
        testSrcInstance.testFunc().interfaceTest();
    }
}

В строке return (Child)x; я получил "ClassCastException", и я очень смущен этим, поскольку Child расширяется Base, поэтому x должен быть успешно преобразован в Child.этот вид разговора имитируется некоторыми кодами Android:

getText() метод EditText - это:

public Editable getText() {
        return (Editable) super.getText();
    }

, а суперкласс EditText - TextView,из которых getText() метод:

public CharSequence getText() {
    return mText;
}

mText является CharSequence, и обратите внимание, что Editable расширяет CharSequence, так что вы можете видеть, эти коды Android приводят CharSequence к Editable, простокак я, приведи Base к Child, какая разница?

1 Ответ

4 голосов
/ 11 февраля 2012

в строке return (Child) x; я получил «ClassCastException», я очень смущен этим, потому что Child расширяет Base, поэтому x следует успешно преобразовать в Child.

Нет, это будет работать только в том случае, если x * действительно ссылается на экземпляр некоторого типа, который реализует Child. В этом случае это не так - это относится только к экземпляру BaseClass. Это не указывает на какое-либо поведение для interfaceTestChild(), так что же произойдет, если вы сможете вызвать его?

Base x = new BaseClass();
// Imagine this had worked...
Child child = (Child)x;
// What would this do? There's no implementation!
child.interfaceTestChild();

Java позволяет приводить только к типу, который на самом деле поддерживает значение, то есть к какому-либо типу в иерархии наследования объекта, к которому относится значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...