Вопрос об абстрактных классах и наследовании - PullRequest
0 голосов
/ 10 мая 2011

У меня есть абстрактный класс Customer, который имеет некоторые атрибуты, общие для всех клиентов (ex id, name, фамилия).

Тогда у меня есть несколько классов, таких как PriorityCustomers, которые имеют специальные уникальные поля, такие как (высота, ширина), MidPriorityCustomers и т. Д.

Когда я делаю это:

Customer customer = new PriorityCustomer();

Я не могу получить доступ к приоритетным методам клиента. Когда я пытаюсь сделать это иначе, я не могу создать экземпляр абстрактного класса.

Я использую это потому, что хочу обрабатывать всех клиентов в одном и том же процессе, только те, кто имеет особые потребности, делают для них что-то особенное.

Поэтому мой метод возвращает тип Customer. Я принимаю неправильное решение с дизайном здесь? Кто-нибудь может что-то предложить?

Забыл упомянуть :

Поля, которые есть у меня в родительском абстрактном классе, у меня нет полей в специальных классах клиентов и наоборот. (Нет высоты, ширины в классе Customer, но в классе PriorityCustomers)

Ответы [ 6 ]

4 голосов
/ 10 мая 2011

Звучит так, будто у вас есть метод супер-процесса, когда вам нужны конкретные.

abstract class Customer {
    public abstract returnType process(args);
}

class PriorityCustomer extends Customer {
    public returnType process(args) {
       // process PriorityCustomer 
    }
}

class MidPriorityCustomer extends Customer {
    public returnType process(args) {
       // process MidPriorityCustomer 
    }
}

Тогда все, что вам нужно, это

for(Customer customer: customers)
    customer.process(args);

Это позволит вам обрабатывать все типы клиентов, где каждый тип клиента знает, какая специальная обработка ему нужна.

3 голосов
/ 10 мая 2011

Ваша ссылка на объект клиента, поэтому видны только методы на клиенте.Если вы хотите вызвать методы в PriorityCustomer, вам нужно сделать ссылку типа PriorityCustomer.Если вам нужно вызвать методы для PriorityCustomer, вам нужно сделать:

PriorityCustomer customer = new PriorityCustomer();

Если вы хотите, чтобы для PriorityCustomer было определенное поведение, переопределите методы для объекта Customer и используйте свой код:

 Customer customer = new PriorityCustomer();

Поэтому, если у Customer есть метод с именем processOrder(), вы можете переопределить его в PriorityCustomer.Когда начинается полиморфизм, вы можете вызвать processOrder() по ссылке Customer, и будет выполняться метод PriorityCustomer.Вот как вы задаете для подклассов различное поведение, но просто используете ссылки на суперклассы в своем коде.

1 голос
/ 10 мая 2011

Преимущество объявления переменной как суперкласса состоит в том, что могут использоваться любые дочерние элементы, которые используются для создания экземпляра этой переменной.

Недостатком является то, что вы ограничены интерфейсом объявленного класса;Вы можете явно привести Customer к PriorityCustomer, но вы должны использовать instanceof, чтобы убедиться, что он безопасен:

Customer customer = new PriorityCustomer();
if (customer instanceof PriorityCustomer) {
    height = ((PriorityCustomer)customer).getHeight();
}

Итак, подведем итог: вы, как правило, захотите объявить переменную как любой класс, который вам нужно использовать.Если вы обнаружите, что выполняете много явного приведения, вы можете переосмыслить структуру своего класса.

0 голосов
/ 10 мая 2011
public Customer getTheCustomer() {
    // return one of the subclasses of Customer
}
....


Customer c = getTheCustomer();
if (c instanceof PriorityCustomer) {
    PriorityCustomer pc = (PriorityCustomer) c;
    // do something with pc
} else if (c instanceof MidPriorityCustomer) {
    MidPriorityCustomer mpc = (MidPriorityCustomer) c;
    // do something with mpc

... et cetera ...
0 голосов
/ 10 мая 2011

Вы можете использовать instanceof, чтобы помочь в этом отношении

Customer customer = new PriorityCustomer();
if ( customer instanceof PriorityCustomer ) {
    ((PriorityCustomer)customer).somePriorityCustomerSpecificMethod();
}

Очевидно, это надуманный пример.

0 голосов
/ 10 мая 2011

Идея иметь общий базовый класс состоит в том, чтобы объединить общие функциональные возможности всех клиентов в один класс и построить на его основе определенный тип клиентов.Если вы хотите получить доступ к PriorityCustomer определенным свойствам и уверены, что у вас есть экземпляр PriorityCustomer, вы можете выполнить приведение.

float height = ((PriorityCustomer)customer).height;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...