Во-первых, это не Java. Вы не можете написать такие методы установки геттера в Java: (Это 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 таким образом, чтобы экземпляр класса Customer мог содержать либо NormalStrategy, либо HappyHourStrategy в качестве переменной экземпляра.
Таким образом, если вы видите основной метод:
var firstCustomer = new Customer(normalStrategy);
Первый клиент - это клиент, имеющий NormalStrategy (не счастливый час).
В то время как второй клиент - это клиент, имеющий HappyHourStrategy.
Customer secondCustomer = new Customer(happyHourStrategy);
Итак под сомнение: Я знаю, что вы не можете создавать экземпляры интерфейсов.
Вы абсолютно правы. Так как это работает? Ответ таков: реализация вводится в ваш код через конструктор или вызов метода.
Здесь она вводится через конструктор.
var normalStrategy = new NormalStrategy();
var firstCustomer = new Customer(normalStrategy);
Итак, ваш код знает об интерфейсе или абстрактный класс и может вызывать все, что определено в этом контракте.