【问题标题】:Question about abstract classes and inheritance关于抽象类和继承的问题
【发布时间】:2011-05-10 21:32:16
【问题描述】:

我有一个名为 Customer 的抽象类,它有一些在所有客户之间共享的属性(例如 ID、姓名、姓氏)。

然后我有几个类,例如PriorityCustomers,它们具有特殊的唯一字段,例如(高度、宽度)、MidPriorityCustomers 等。

当我这样做时:

Customer customer = new PriorityCustomer();

我无法访问优先客户方法。当我以其他方式尝试时,我无法实例化抽象类。

我使用它是因为我想通过相同的流程处理所有客户,只有那些有特殊需求的客户才能为他们做一些特别的事情。

因此,我的方法返回 Customer 类型。我在这里的设计是否做出了错误的决定?有人可以提出一些建议吗?

忘了说

我在父抽象类中的字段在特殊客户类中没有,反之亦然。(在客户类中没有高度和宽度,但在 PriorityCustomers 类中)

【问题讨论】:

    标签: java inheritance


    【解决方案1】:

    听起来你有一个超级处理方法,当你想要特定的时候。

    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);
    

    这将允许您处理所有客户类型,其中每个客户类型都知道它需要什么特殊处理。

    【讨论】:

      【解决方案2】:

      您的引用是一个客户对象,因此只有客户上的方法是可见的。如果要调用 PriorityCustomer 上的方法,则需要引用 PriorityCustomer 类型。如果您需要在 PriorityCustomer 上调用方法,您需要这样做:

      PriorityCustomer customer = new PriorityCustomer();
      

      如果您想要 PriorityCustomer 的特定行为,请覆盖 Customer 对象上的方法并使用您的代码:

       Customer customer = new PriorityCustomer();
      

      因此,如果客户有一个名为processOrder() 的方法,您可以在 PriorityCustomer 中覆盖它。当多态性开始时,您可以在 Customer 引用上调用 processOrder(),它将是 PriorityCustomer 上的方法,它将被执行。这就是您为子类赋予不同行为的方式,但只需在代码中使用超类引用即可。

      【讨论】:

        【解决方案3】:

        将变量声明为超类的好处是可以使用任何用于实例化该变量的子类。

        缺点是你仅限于声明的类的接口;您可以将 Customer 显式转换为 PriorityCustomer,但您应该使用 instanceof 来确保它是安全的:

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

        总而言之:您通常希望将变量声明为您需要使用的任何类。如果您发现自己做了很多显式转换,您可能需要重新考虑您的类结构。

        【讨论】:

          【解决方案4】:

          拥有一个通用基类的想法是将所有客户的通用功能归为一个类,并在其之上构建特定类型的客户。如果您想访问 PriorityCustomer 的特定属性,并且确定您有一个 PriorityCustomer 实例,则可以进行强制转换。

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

          【讨论】:

            【解决方案5】:

            你可以使用 instanceof 在这方面提供帮助

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

            显然这是一个人为的例子。

            【讨论】:

              【解决方案6】:
              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 ...
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-03-15
                • 2013-08-04
                • 2012-11-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多