Вам здесь не хватает ключевой концепции: покупатель есть покупатель. Будь то мелкий, золотой, крупный, серебряный, заслуживающий доверия, банкрот; это клиент. На мой взгляд, это часть базовой c OOP идентификации объекта.
За этими предложениями, в которых утверждается очевидное, стоит фундаментальная концепция: у вас должно быть определение «клиент» и все, что вы называете клиентом должны соответствовать ему, хотя можно по-прежнему выбирать, «как» они ему соответствуют.
Теперь, чтобы сделать это практичным: если у вас есть класс Customer
, который расширен на MinorCustomer
и другие под- классов, вам необходимо объявить общее поведение, применимое ко всем клиентам в классе Customer
. От этого зависит полиморфизм. Если «клиент» не знает ничего вроде «авторизован», то вы не можете ввести polymorphi c поведение «авторизовано».
Для использования примера:
class Customer {
final int getAge() {
//return
}
boolean isAuthorized() {
return true;
}
}
class MinorCustomer extends Customer {
private boolean parentPresent;
@Override
boolean isAuthorized() {
return this.parentPresent;
}
}
В приведенном выше коде «определение» «клиента» включает понятие «авторизованный». Однако «второстепенный клиент» может выбрать, «как» он соответствует этому определению.
Все очень просто: вам нужен Customer
API, чтобы объявить метод isAuthorized()
, и это переопределено в MinorCustomer
. Это, конечно, может быть неадекватным для вашего дизайна; и это нормально: это просто означало бы, что место не подходит для поведения polymorphi c (и, возможно, также, что следует поставить под сомнение отношения наследования). И вы можете распространить это рассуждение на другие примеры, отношения родитель-потомок должны включать в себя объявление поведения в родительском элементе, чтобы полиморфизм был применим.
Что касается механики чистого создания связанных объектов, Пост Макото дает хороший подход.