Pregunta sobre clases abstractas y herencia

Tengo una clase abstracta llamada Customer que tiene algunos atributos compartidos entre todos los clientes (ex id, nombre, apellido).

Entonces tengo pocas clases como PriorityCustomers que tienen campos únicos especiales como (alto, ancho), MidPriorityCustomers etc.

Cuando hago esto:

Customer customer = new PriorityCustomer();

No puedo acceder a los métodos de cliente prioritarios. Cuando lo intento de otra manera, no puedo crear una instancia de la clase abstracta.

Estoy usando esto porque quiero procesar a todos los clientes a través del mismo proceso, solo aquellos que tienen necesidades especiales hacen algo especial por ellos.

Por tanto, mi método está volviendo Customer escribe. ¿Estoy tomando una decisión incorrecta con el diseño aquí? ¿Alguien puede sugerir algo?

Olvide mencionar :

Los campos que tengo en mi clase abstracta principal no los tengo en clases especiales de clientes y al revés. (Sin altura, ancho en la clase Cliente, pero esos están en la clase PriorityCustomers)

preguntado el 10 de mayo de 11 a las 13:05

6 Respuestas

Parece que tienes un método de superproceso cuando quieres unos específicos.

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

Entonces todo lo que necesitas es

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

Esto le permitirá procesar todos los tipos de Clientes donde cada tipo de Cliente sepa qué procesamiento especial necesita.

contestado el 10 de mayo de 11 a las 17:05

Su referencia es a un objeto de cliente, por lo que solo los métodos en el cliente son visibles. Si desea llamar a los métodos en PriorityCustomer, debe hacer la referencia de tipo PriorityCustomer. Si necesita llamar a métodos en PriorityCustomer, debe hacer lo siguiente:

PriorityCustomer customer = new PriorityCustomer();

Si desea comportamientos específicos para PriorityCustomer, anule los métodos en el objeto de cliente y use su código:

 Customer customer = new PriorityCustomer();

Entonces, si el cliente tiene un método llamado processOrder(), puede anularlo en PriorityCustomer. Cuando el polimorfismo se activa, puede llamar processOrder() en la referencia del Cliente y será el método en PriorityCustomer el que se ejecutará. Así es como le das a las subclases diferentes comportamientos, pero solo usa las referencias de superclase en tu código.

contestado el 10 de mayo de 11 a las 17:05

La ventaja de declarar la variable como una superclase es que se puede usar cualquier elemento secundario que se use para instanciar esta variable.

La desventaja es que está limitado a la interfaz de la clase declarada; Puede enviar explícitamente el Cliente a PriorityCustomer, pero debe usar instanceof para asegurarse de que sea seguro:

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

Entonces, en resumen: generalmente querrá declarar la variable como cualquier clase que necesite usar. Si te encuentras haciendo mucho casting explícito, es posible que desees reconsiderar tu estructura de clases.

contestado el 10 de mayo de 11 a las 17:05

La idea de tener una clase base común es agrupar la funcionalidad común de todos los clientes en una clase y construir un tipo específico de clientes sobre ella. Si quieres acceder PriorityCustomer propiedades específicas y si está seguro de que tiene una PriorityCustomer Por ejemplo, puedes hacer un yeso.

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

contestado el 10 de mayo de 11 a las 17:05

Puede utilizar instanceof para ayudar en este sentido.

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

Obviamente, este es un ejemplo artificial.

contestado el 10 de mayo de 11 a las 17:05

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

contestado el 10 de mayo de 11 a las 17:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.