Это является следствием принципа замены Лискова , который гласит (суммировано):
Если S и T являются объектами, а T является подтипом из S, тогда T может использоваться там, где ожидается S.
String
- это подтип Object
, поэтому, если ваша операция присваивания ожидает Object
, тогда он с радостью примет Object
или любой из его подтипов.
(Примечание: Object
не является String
. Все String
s Object
с, но не все Object
с String
с.)
Это не означает, что вы получаете доступ к любому методов подтипа.Учитывая иерархию наследования, Object
не имеет ни малейшего понятия о каком-либо из специфических методов своих детей, равно как и не может - нет никакого способа сообщить классу предка о возможностях его потомка.Поскольку Object
не имеет никакого метода substring
, связанного с ним, ваш код правильно приводит к ошибке компиляции.
(И это следует делать, учитывая, что Object
является предком all классы. Нет никакой гарантии, что любой данный Object
является String
.)
Постоянный совет - не использовать чрезмерно неспецифический тип объекта (по мере продвижения по иерархической цепочке).возможности становятся менее специфичными - вы теряете функциональность при переходе на Object
) для достижения чего-то определенного для более конкретного типа.