что означает слово «обещать» в контексте кастинга, компилятора? - PullRequest
0 голосов
/ 19 сентября 2018

Из книги Java:

Компилятор проверяет, что вы не обещаете слишком много, когда сохраняете значение в переменной.Если вы назначаете ссылку на подкласс для переменной суперкласса, вы обещаете меньше, и компилятор просто позволит вам это сделать.Если вы назначите ссылку на суперкласс для переменной подкласса, вы получите обещание больше.Затем вы должны использовать приведение, чтобы ваше обещание могло быть проверено во время выполнения.

Я пойму, если вы сможете объяснить мне, что означает "обещать" в техническом плане,Я посмотрел в словарях, но слово не вписывается в контекст этого абзаца.

1 Ответ

0 голосов
/ 19 сентября 2018

Это не стандартная терминология, но автор, кажется, использует ее, чтобы (попытаться) сделать ее доступной для начинающих.(Что не легко.) В основном, они говорят, что если у вас есть:

class Base {
    public void baseMethod() {
        // ...
    }
}
class Derived extends Base {
    public void derivedMethod() {
        // ...
    }
}

Вы можете сделать это:

Base b = new Derived();

... потому что все функцииопределения типа Base (baseMethod) доступны для объекта, который вы назначаете (экземпляр Derived).Вы «обещаете», что объект, на который ссылается b, будет иметь baseMethod, и он имеет.

Но вы не можете сделать это:

Derived d = new Base();

...потому что тип Derived определяет функции (derivedMethod), которых у объекта, который вы назначаете (экземпляр Base), нет.Вы «обещаете», что объект, на который ссылается d, будет иметь derivedMethod, но это не так, поэтому вы «слишком много обещаете».


Повторный комментарий:

как происходит кастинг во втором примере?

Это не входит в этот пример.Приведение не меняет того, что представляет собой объект, просто вид ссылки на него. Have

Но предположим, что у вас было что-то вроде этого:

void someMethod(Base obj) {
    if (obj instanceof Derived) { // Just an example, `instanceof` is usually
                                  // an anti-pattern
        Derived d = (Derived)obj;
        // ...
    }
}

Метод получает объект иимеет только Base ссылку на него.Но затем код проверяет и обнаруживает, что объект на самом деле является Derived (или подклассом Derived), поэтому он использует приведение, чтобы изменить тип имеющейся ссылки, чтобы он мог использовать функции Derived.Таким образом, кастинг вошел в него таким образом.

Опять же, обратите внимание, что использование instanceof является анти-паттерном в девяти из десяти ситуаций.В девяти случаях из десяти вы хотите провести рефакторинг кода, чтобы передать в интерфейс тип интерфейса, который определяет только те функции, которые необходимы коду.Десятая ситуация редка.: -)

И будет ли всегда успешным приведение во втором?

Только если вы точно знаете, что объект относится к тому типу, который выприведение к или подкласс этого типа.Если вы этого точно не знаете, приведение к нему может привести к ClassCastException.


¹ ... за исключением особого случая примитивов приведения (например, int) к объектам-оболочкам (таким как Integer) и наоборот.И даже тогда он не изменяет объект, он просто создает объект (при приведении к типу-обертке) или создает примитив (при преобразовании в примитивный тип).

...