I have 4 classes
public class User {
private Account account;
public void setAccount(Account account) {
this.account = account;
}
public Account getAccount() {
return this.account;
}
}
public abstract class Account {
private double balance;
private String password;
private String userName;
private String mobileNumber;
private Provider provider;
// some getters and setters
}
public class BankAccount extends Account {
// this not in the parent class
private String accountNumber;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber ;
}
}
public class WalletAccount extends Account {
}
How I redesign this to make like this
Account account = new BankAcccount() ;
account.getAccountNumber() ;
without using
instanceof
or casting like((BankAccount) account)getAccountNumber() ;
Redesign the classes to allow call of the BankAccount
methods without using instanceof
or casting using design patterns or add more classes any approach.
In the simple case you can add an abstract
method to the parent class.
public abstract class Account {
private double balance;
private String password;
private String userName;
private String mobileNumber;
private Provider provider;
// some getters and setters
public abstract String getAccountNumber();
}
This makes an accountNumber
property to be abstract. Every non-abstract subclass should implement the abstract method of Account
class.
Then you can use
Account account = new BankAcccount() ;
account.getAccountNumber() ;
without using
instanceof
or casting like((BankAccount) account)getAccountNumber() ;
This is allowed because abstract
methods can use polymorphism.
Another way is to use interface to access the property of some subclass. Another subclass might not implement this interface if it doesn't have such property. When you need to access the property then you upcast to the interface without instanceof
.
public interface AccountNumberAware {
public String getAccountNumber();
}
public abstract class Account implements AccountNumberAware {
private double balance;
private String password;
private String userName;
private String mobileNumber;
private Provider provider;
// some getters and setters
// dummy implementation of interface
public String getAccountNumber() {
return null;
}
}
public class BankAccount extends Account {
// this not in the parent class
private String accountNumber;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber ;
}
}
Then you can use
Account account = new BankAcccount() ;
account.getAccountNumber() ;