简体   繁体   English

接口实现和常用功能

[英]Interface implementation and common function

I have the following requirement, 我有以下要求,

  • There will be 2(or more) different classes to perform same kind of operation(in different ways). 将有2个(或更多)不同的类来执行相同类型的操作(以不同的方式)。 Therefore I decided to create an interface. 因此,我决定创建一个接口。 Then I implemented these 2 classes with my interface. 然后,我使用界面实现了这两个类。
  • Now, from another class I will be using the object of type Interface and calls functions. 现在,从另一个类中,我将使用接口类型的对象并调用函数。 Everything works fine. 一切正常。
  • Then a new requirement came to create a common functionality that applies to both classes. 然后,出现了一项新要求,即创建适用于两个类的通用功能。
  • I don't want to define same function in both classes. 我不想在两个类中定义相同的函数。 And interface dont allows function definition. 和接口不允许功能定义。
  • First I thought abstract class will be useful. 首先,我认为抽象类会很有用。 Because it allows function definition and abstract functions. 因为它允许函数定义和抽象函数。 But abstract classes cant be instantiated and also I need to create objects with individual class types. 但是不能实例化抽象类,并且我还需要创建具有单独类类型的对象。

Sorry I cant find a simple way to define my problem. 对不起,我找不到定义问题的简单方法。 It feels like a solution that spring framework provides. 感觉就像是spring框架提供的解决方案。 But I need to know how to acheive this from a Java/C# application. 但是我需要知道如何从Java / C#应用程序中实现这一点。

It sounds like you want an abstract class implementing the common functionality, but still have two concrete classes for the distinct functionality. 听起来您想要一个实现通用功能的抽象类,但是对于不同的功能仍然有两个具体的类。 You may or may not still want to keep the interface as well. 您可能也可能不想保留界面。 So the options are: 因此,选项为:

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

or just 要不就

         Abstract
          class
            ^
           / \
   Concrete   Concrete 
   class 1    class 2

Code which wants to use these classes just uses the interface or abstract class. 想要使用这些类的代码仅使用接口或抽象类。 How you configure which concrete class to use were will depend on your exact requirements - but presumably you'd already tackled that in the earlier version. 如何配置要使用的具体类取决于您的确切要求-但大概您已经在较早版本中解决了这一问题。

A common pattern for this is: 常见的模式是:

  1. Define the interface (as you've done). 定义接口(完成后)。
  2. Create an abstract class which implements the common functionality in terms of the non-common functionality. 创建一个抽象类,该类根据非通用功能实现通用功能。
  3. Extend this abstract class to provide the non-common functionality. 扩展此抽象类以提供非通用功能。

A lot of JDK classes do this. 许多JDK类都可以做到这一点。 For instance, the List<T> interface has an AbstractList<T> abstract class, which is extended to provide both ArrayList<T> and LinkedList<T> . 例如, List<T>接口具有AbstractList<T>抽象类,该抽象类被扩展为提供ArrayList<T>LinkedList<T>

A simple (if contrived) example would be something like: 一个简单的(如果有人为的)示例将类似于:

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

Note that once Java 8 arrives, you'll be able to define methods in interfaces. 请注意,一旦Java 8到来,您就可以在接口中定义方法。 These are commonly known as "defender methods." 这些通常称为“防御者方法”。 When that happens, you may not need the abstract class -- depending on whether that common functionality needs to maintain its own state (interfaces still won't be able to define instance state). 发生这种情况时,您可能不需要抽象类-取决于该通用功能是否需要维持其自己的状态(接口仍然无法定义实例状态)。 But for now, the interface-abstract-concrete pattern often works well. 但是就目前而言,界面抽象的模式通常效果很好。

You can try to avoid using simple interface and use strategy pattern: 您可以尝试避免使用简单的界面并使用策略模式:

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

Create a concrete class (or better abstract class) that implements your interface, and contains your "common functionality", Now you can extend this class (Hierarchy) with two (or more) classes. 创建一个实现您的接口并包含“通用功能”的具体类(或更好的抽象类),现在您可以使用两个(或更多)类来扩展该类(层次结构)。

there are many more ways of designing this requirement. 设计此需求的方法还有很多。 And I am not sure If mine is best either. 而且我也不确定我的最好。

Just to add on to Jon Skeet's answer, you need to think as to what kind of relationship your classes have with the interface or the intended abstract class. 只是为了补充Jon Skeet的答案,您需要考虑您的类与接口或预期的抽象类之间的关系。 If the relationship is between the behaviour laid out in the interface is has-a then the interface is the right choice, and if it is an is-a relationship, you can go with an abstract class. 如果接口之间的行为之间的关系为has-a,则接口是正确的选择;如果接口为is-a,则可以使用抽象类。

In another scenario, you can also check if the relationship is has-a, and the new common functionality that you want to implement is an is-a relationship, then apart from option by Jon, you can use something like this: 在另一种情况下,您还可以检查该关系是否为has-a,并且要实现的新通用功能是is-a关系,那么除了Jon的选择之外,您还可以使用以下方法:

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

for eg: 例如:

interface IParent{}

abstract class Parent{}

class Child1: Parent, IParent{}

class Child2: Parent, IParent{}

It all depends how you design your classes for future use. 这完全取决于您如何设计类以供将来使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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