Как правильно использовать полиморфизм для вызова методов нужного класса в Java - PullRequest
3 голосов
/ 07 мая 2020

Предположим, что у меня есть система регистрации mov ie в театре.

И что у меня есть родительский Customer класс и дочерний MinorCustomer класс.

MinorCustomer имеет метод isAuthorized(), , которого нет в Customer , который возвращает true или false, предназначенный для вызова, если выбранный mov ie не предназначен для несовершеннолетних без сопровождения

Теперь при создании экземпляров классов для хранения информации в структуре данных (в зависимости от того) я сталкиваюсь с проблемой, которую я не могу вызвать isAuthorized() в случае, если клиент является несовершеннолетним.

Это все гипотетически, поэтому программы с этим кодом нет, но при условии, что случай будет

Customer cust = new Customer()
if(cust.getAge() < 18) {
    cust = (MinorCustomer) cust;
    cust.isAuthorized();
}

Однако этот код будет недействительным, поскольку он все равно будет рассматривать cust как экземпляр Customer, а не MinorCustomer. Я знаю, что могу просто использовать оператор if, чтобы определить, хочу ли я создать новый экземпляр Customer / Minor в зависимости от возраста, но я хотел бы воспользоваться преимуществами полиморфизма, чтобы легко изменить тип без необходимости писать более жесткие код.

Ответы [ 3 ]

1 голос
/ 07 мая 2020

Создайте CustomerFactory, который вместо этого выдает клиента соответствующего типа на основе параметра возраста.

Полагаясь на принцип, что

class Customer { }
class MinorCustomer extends Customer { }

... тогда реализация ваша фабрика может быть:

class CustomerFactory {
    public static Customer createInstance(final int age) {
        if(age < 18) {
            return new MinorCustomer();
        } else {
            return new Customer();
        }
    }
}

... которая затем может быть использована в вашем коде следующим образом.

Customer cust = CustomerFactory.createInstance(17);

Вы можете принудительно применять instanceof проверки в методах, которые потребуйте , чтобы Customer не было MinorCustomer, или вы можете проверить возраст клиента, так как вы все равно можете получить эту информацию бесплатно.

0 голосов
/ 07 мая 2020

Вам здесь не хватает ключевой концепции: покупатель есть покупатель. Будь то мелкий, золотой, крупный, серебряный, заслуживающий доверия, банкрот; это клиент. На мой взгляд, это часть базовой 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 (и, возможно, также, что следует поставить под сомнение отношения наследования). И вы можете распространить это рассуждение на другие примеры, отношения родитель-потомок должны включать в себя объявление поведения в родительском элементе, чтобы полиморфизм был применим.

Что касается механики чистого создания связанных объектов, Пост Макото дает хороший подход.

0 голосов
/ 07 мая 2020

Вам нужно добавить свойство isAuthrorized в класс Customer.

и logi c должно понравиться

    Customer cust = new Customer(...);
    if(cust.getAge() > 18){
      //skip authorization
      cust.isAuthrorized = true;
    }else{
      authorize.user(cust);
      //set isAuthrorized in authorization class based on user authentication fail or not
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...