@Getter
public abstract class BaseProduct {
Account account = new Account();
}
public class ProductOne extends BaseProduct {
FieldOne fieldOne = new FieldOne();
}
public class ProductTwo extends BaseProduct {
FieldTwo fieldTwo = new FieldTwo();
}
public class Account {
public TypeOne methodOne() {
return typeOne;
}
public TypeTwo methodTwo() {
return typeTwo;
}
}
public class MyClass {
ProductOne productOne = new ProductOne();
productOne.getAccount().methodOne(); //accessible
productOne.getAccount().methodTwo(); //not accessible (error)
ProductTwo productTwo = new ProductTwo();
productTwo.getAccount().methodOne(); //not accessible (error)
productTwo.getAccount().methodTwo(); //accessible
}
So, I have two classes (ProductOne and ProductTwo) which inherits from a Base Abstract class(BaseProduct). The Base Abstract class in turns creates an object of another class (Account)
Now i want to restrict access to some methods of Account class for ProductOne objects and similarly restrict access for some other methods for ProductTwo objects.
I think I need to create Account class as an Interface/Abstract class and create different implementations for it. Is this understanding correct? Can you please show me how to do that exactly?
It seems you have two lines of Product
concepts here. What you can do is make both BaseProduct
and Account
abstract and use generics.
public abstract class BaseProduct<A extends Account> {
public abstract A getAccount();
}
class ProductOne extends BaseProduct<TypeOneAccount> {
FieldOne fieldOne = new FieldOne();
}
class ProductTwo extends BaseProduct<TypeTwoAccount> {
FieldTwo fieldTwo = new FieldTwo();
}
This will allow concrete "product" types to be bound to specific Account
types.
Then, remove methodOne
and methodTwo
from Account
and have them implemented in actual "type one" and "type two" classes:
public abstract class Account {
}
public class TypeOneAccount extends Account {
public TypeOne methodOne() {
return typeOne;
}
}
public class TypeTwoAccount extends Account {
public TypeTwo methodTwo() {
return typeTwo;
}
}
With this, both of the following will fail at compile time:
//fails because productOne.getAccount() returns a TypeOneAccount object,
//which doesn't have methodTwo()
productOne.getAccount().methodTwo()
//fails because productTwo.getAccount() returns a TypeTwoAccount object,
//which doesn't have methodOne()
productTwo.getAccount().methodOne()