接口实现和通用功能

时间:2013-11-29 06:43:58

标签: c# java oop interface abstract-class

我有以下要求,

  • 将有2个(或更多)不同的类来执行相同类型的操作(以不同的方式)。因此我决定创建一个界面。然后我用我的界面实现了这两个类。
  • 现在,从另一个类我将使用Interface类型的对象并调用函数。一切正常。
  • 然后一个新的要求来创建一个适用于这两个类的通用功能。
  • 我不想在两个类中定义相同的功能。并且接口不允许函数定义。
  • 首先,我认为抽象类是有用的。因为它允许函数定义和抽象函数。但是抽象类不能被实例化,我还需要创建具有单独类类型的对象。

抱歉,我无法找到一种简单的方法来定义我的问题。感觉就像Spring框架提供的解决方案。但我需要知道如何从Java / C#应用程序中实现这一点。

5 个答案:

答案 0 :(得分:5)

听起来你想要一个实现通用功能的抽象类,但仍然有两个具体的类用于不同的功能。您可能也可能不想保留界面。所以选项是:

        Interface
            ^
            |
         Abstract
          class
            ^
           / \
   Concrete   Concrete 
   class 1    class 2

或只是

         Abstract
          class
            ^
           / \
   Concrete   Concrete 
   class 1    class 2

想要使用这些类的代码只使用接口或抽象类。如何配置要使用的具体类将取决于您的确切要求 - 但可能您已经在早期版本中解决了这个问题。

答案 1 :(得分:2)

常见的模式是:

  1. 定义界面(正如您所做的那样)。
  2. 创建一个抽象类,根据非常用功能实现通用功能。
  3. 扩展此抽象类以提供非常见功能。
  4. 许多JDK类都这样做。例如,List<T>接口有一个AbstractList<T>抽象类,它被扩展为提供ArrayList<T>LinkedList<T>

    一个简单的(如果设计的)例子可能是:

    interface IntThingy {
        int getValue();
        int getDoubeValue();
    }
    
    abstract class AbstractIntThingy implements IntThingy {
        @Override
        public int getDoubleValue() {
            return getValue() * 2;
        }
    }
    
    class ConstantFourtyTwo extends AbstractIntThingy {
        @Override
        public int getValue() {
            return 42;
        }
    }
    
    class ConstantIntThingy extends AbstractIntThingy {
        private final int value;
    
        ConstantIntThingy(int value) {
            this.value = value;
        }
    
        @Override
        public int getValue() {
            return value;
        }
    }
    

    请注意,一旦Java 8到达,您将能够在接口中定义方法。这些通常被称为“防御者方法”。当发生这种情况时,您可能不需要抽象类 - 取决于该常用功能是否需要维护其自身状态(接口仍然无法定义实例状态)。但就目前而言,界面抽象 - 具体模式通常效果很好。

答案 2 :(得分:1)

您可以尝试避免使用简单的界面并使用策略模式:

http://en.wikipedia.org/wiki/Strategy_pattern

答案 3 :(得分:0)

创建一个实现接口的具体类(或更好的抽象类),并包含“常用功能”。现在,您可以使用两个(或更多)类扩展此类(Hierarchy)。

还有很多方法可以设计这个要求。 我不确定我的最好也是。

答案 4 :(得分:0)

为了补充Jon Skeet的答案,你需要考虑你的类与接口或预期的抽象类有什么样的关系。如果关系介于接口中的行为是has-a,那么接口是正确的选择,如果它是is-a关系,你可以使用抽象类。

在另一种情况下,您还可以检查关系是否为has-a,并且要实现的新常用功能是is-a关系,然后除了Jon的选项之外,您可以使用以下内容:

           Abstract
            class
              ^
             / \
Interface            Interface
     \                /    
     Concrete   Concrete 
     class 1    class 2

例如:

interface IParent{}

abstract class Parent{}

class Child1: Parent, IParent{}

class Child2: Parent, IParent{}

这完全取决于您如何设计课程以供将来使用。