Я думаю, вы, вероятно, сделали неправильный выбор имен: я бы подумал, что RestrictedUser
будет подклассом User
, а не наоборот, поэтому я буду использовать UnrestrictedUser
в качестве подкласса.
Если вы повысите UnrestrictedUser
до RestrictedUser
, ваша ссылка сможет получить доступ только к методам, объявленным в RestrictedUser
. Однако, если вы вернете его обратно к UnrestrictedUser
, у вас будет доступ ко всем методам. Поскольку объекты Java знают, какой тип они на самом деле, все, что на самом деле является UnrestrictedUser
, всегда может быть приведено обратно к нему, независимо от того, какой тип ссылки вы используете (даже Object
). Здесь неизбежна и часть языка. Тем не менее, вы можете скрыть это за каким-то прокси, но в вашем случае это, вероятно, побеждает цель.
Кроме того, в Java все нестатические методы являются виртуальными по умолчанию. Это означает, что если UnrestrictedUser
переопределяет некоторый метод, объявленный в RestrictedUser
, то будет использоваться версия UnrestrictedUser
, даже если вы обращаетесь к ней через ссылку RestrictedUser
. Если вам нужно вызвать версию родительского класса, вы можете сделать не виртуальный вызов, вызвав RestrictedUser.variableName.someMethod()
. Однако вам, вероятно, не следует использовать это очень часто (наименьшая из причин заключается в том, что он нарушает инкапсуляцию).