Question about abstract classes and inheritance
I have a abstract class called Customer
which has some attributes shared amongst all custome开发者_Go百科rs(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 ...
精彩评论