The problem here is that you've been mislead to express these kind of relationships with inheritance. You have not done anything wrong, this problem typifies the problems with inheritance and why it is generally not favorable to composition.
Favor composition to inheritance
There are many approaches to this issue, but the following is what stands out to me as the simplest:
First, you have a User class, unlike in your hierarchy, this represents a system user, and that is it.
Obviously, these are quick layouts, replace the properties with getters, setters, ect.
interface HasSessionId
{
ID;
}
interface CanCheckPermission
{
HasPermissionTo(permission);
}
class AnnoUser implements CanCheckPermission, HasSessionId
{
ID;
}
class RegisterUser implements CanCheckPermission, HasSessionId
{
ID;
UserName;
FirstName;
LastName;
Login; //Sometimes it is helpful to separate the login into a a different concept to make impersonation easier, ect, you may or may not need this in your system.
}
Next, you have your system roles. This is a completely different thing than a user. Any common behaviors or properties they may have are in an interface. Interfaces implement only minimal functionality and should not be viewed as a base class without implementation. They only express something the System roll can do.
interface IsAUser
{
User;
}
interface CanBuy
{
Buy(product);
}
Our individual system rolls can now implement these interfaces to express their available functions, and are free to do things differently if they want, but they may have common behavior we want to leverage, which is where the buying utility comes in.
class BuyingUtility
{
//static stuff is generally bad, but this is the closest Java has to functions. Avoid static fields as much as possible
static Buy(product, IsAUser) { /*buy logic*/ }
}
class Admin implements IsAUser, CanBuy, CanSell
{
User;
Buy(product)
{
BuyingUtility.Buy(product, this);
}
}
class BuyerManager implements IsAUser, CanBuy
{
User;
Buy(product)
{
BuyingUtility.Buy(product, this);
}
}