简体   繁体   中英

Question about abstract classes and inheritance

I have a abstract class called Customer which has some attributes shared amongst all customers(ex id, name, surname).

Then I have few classes such as PriorityCustomers which have special unique fields such as(height, width), MidPriorityCustomers etc.

When I do this :

Customer customer = new PriorityCustomer();

I cannot access the priority customer methods. When I try it other way arround I can't instantiate abstract class.

I'm using this because I want to process all customers trough same process only those who have special needs do something special for them.

My method is therefore returning Customer type. Am I making the wrong decision with the design here? Can anybody suggest something?

Forgot to mention :

Fields that I have in my parent abstract class I don't have those in special customer classes and the other way arround.(no height, width in Customer class, but those are in PriorityCustomers class)

Its sounds like you have a super process method when you want specific ones.

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 
    }
}

Then all you need to is

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

This will allows you to process all Customer types where each Customer type knows what special processing it needs.

Your reference is to a Customer Object, so only the methods on Customer are visible. If you want to call the methods on PriorityCustomer you need to make the reference of type PriorityCustomer. If you need to call methods on PriorityCustomer you need to do:

PriorityCustomer customer = new PriorityCustomer();

If you want specific behaviours for PriorityCustomer then override methods on the Customer Object and use your code:

 Customer customer = new PriorityCustomer();

So if Customer has a method called processOrder() , you could override it in PriorityCustomer. When polymorphism kicks in, you can call processOrder() on the Customer reference and it will be the method on PriorityCustomer which will get executed. That's how you give subclasses different behaviours, but just use the superclass references in your code.

The advantage of declaring the variable as a superclass is that any children which are used to instantiate this variable can be used.

The disadvantage is that you are limited to the declared class's interface; You can explicitly cast the Customer to PriorityCustomer, but you should use instanceof to make sure it's safe:

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

So in summary: you will generally want to declare the variable as whatever class you need to use. If you find yourself doing a lot of explicit casting, you may want to rethink your class structure.

The idea of having a common base class is to group the common functionality of all customers in one class and build specific type of customers on top of it. If you want to access PriorityCustomer specific properties and if you are certain you have a PriorityCustomer instance, you can to do a cast.

float height = ((PriorityCustomer)customer).height;

You can use instanceof to help in this regard

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

Obviously this is a contrived example.

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 ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM