菜鸟问题: Java class 有一个成员变量是接口类型。有人可以澄清吗?

Newbie question: Java class has a member variable that is an interface type. Can someone clarify?

有人能给我指出正确的方向吗?我正在学习策略模式 (on wikipedia),在代码示例中,有些地方我不明白。

public IBillingStrategy Strategy的那一行是什么?

class Customer {
    // Get/Set Strategy
    public IBillingStrategy Strategy { get; set; }  // <---- This confuses me

    public Customer(IBillingStrategy strategy) {
        this.drinks = new List<double>();
        this.Strategy = strategy;
    }
 // code that I omitted
}

interface IBillingStrategy {
    double GetActPrice(double rawPrice);
}

我知道您无法实例化接口实例。而且我知道 类 应该用关键字实现接口。不知道那叫什么,我 google 次搜索尝试失败了。

首先,这不是 Java。你不能在 Java 中编写这样的 getter setter 方法:(这是 C#)

public IBillingStrategy Strategy { get; set; }

其次,如果向下滚动,您将看到此接口的实现:

class NormalStrategy : IBillingStrategy
{
    public double GetActPrice(double rawPrice) => rawPrice;
}

class HappyHourStrategy : IBillingStrategy
{
    public double GetActPrice(double rawPrice) => rawPrice * 0.5;
}

所以这基本上是代码到接口的模式。这基本上意味着,您正在设计 Customer class,使 Customer 的实例可以将 NormalStrategy 或 HappyHourStrategy 作为其实例变量。

因此,如果您看到主要方法:

var firstCustomer = new Customer(normalStrategy);

第一个客户是拥有 NormalStrategy 的客户(不是欢乐时光)。

而第二个客户是拥有 HappyHourStrategy 的客户。

Customer secondCustomer = new Customer(happyHourStrategy);

所以来到你的疑问: 我知道你不能实例化接口的实例。

你完全正确。那么这是如何工作的呢? 答案是:通过构造函数或方法调用将实现注入到您的代码中。

这里是通过构造函数注入的

var normalStrategy    = new NormalStrategy();
var firstCustomer = new Customer(normalStrategy);

因此,您的代码知道接口或抽象 class 并且可以调用此合同中定义的任何内容。

这是 Liskov 替换原则 (LSP) 的一个子集,即 SOLID 原则的 L。