首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只允许抽象类知道它的继承者

只允许抽象类知道它的继承者
EN

Stack Overflow用户
提问于 2012-01-16 19:49:28
回答 2查看 280关注 0票数 2

我正在为我的网站支付系统。用户可以从几个支付提供商中选择一个进行支付,但所有支付提供商的行为方式都应该相同。我想把这个行为表示成这样:

代码语言:javascript
复制
public abstract class PaymentProvider {
    private static var methods = Dictionary<String,PaymentProvider>
    {
        {"paypal",new PaymentProviderPaypal()},
        {"worldpay",new PaymentProviderWorldpay()}
    }

    public static Dictionary<String,PaymentProvider> AllPaymentProviders
    {
        get {return methods;}
    }

    public abstract pay();
}

public class PaymentProviderPaypal : PaymentProvider {
    public override pay() {

    }
}

public class PaymentProviderWorldpay : PaymentProvider {
    public override pay() {

    }
}

你应该通过编写PaymentProvider.AllPaymentProviders["key"].pay()来使用它。这个想法是,使用这个类的函数不需要知道底层支付提供程序是如何实现的,它们只需要知道密钥。

但是,目前,如果您可以访问PaymentProvider类,那么您也可以访问继承类。可以实例化继承类的新副本,并以意想不到的方式使用它们。我想封装继承类,以便只有抽象的PaymentProvider知道它们。

我该怎么做呢?像protected这样的不同保护级别在这里不起作用-在Java语言中,protected意味着只有名称空间中的其他类可以使用那个类,但在C#中它意味着其他东西。

我的想法正确吗?或者我应该使用不同的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-16 19:54:12

脑海中浮现出几种选择:

  • 将其放在一个独立于客户端代码的程序集中,并使实现抽象
  • 将实现放在PaymentProvider类中作为私有嵌套类。您仍然可以通过将implementation

设置为分部类来分离源代码--每个PaymentProvider使用一个源文件

如果您不介意在程序集方面将客户端与实现分开,那么第一个选项可能是最干净的。

请注意,在Jamiec的答案提出的更改之后,这两个选项仍然有效-“可见性”部分与继承部分多少是正交的。

(顺便说一句,我希望这个方法被称为Pay(),而不是pay() :)

票数 3
EN

Stack Overflow用户

发布于 2012-01-16 19:57:47

你的继承权有点不可靠,我很想用一种类似但截然不同的方式来继承。

代码语言:javascript
复制
public interface IPaymentProvider
{
  void Pay()
}

// Implementations of IPaymentProvider for PaypalPaymentProvider & WorldpayPaymentProvider

public static class PaymentHelper
{
    private static var providers = Dictionary<String,IPaymentProvider>
    {
        {"paypal",new PaymentProviderPaypal()},
        {"worldpay",new PaymentProviderWorldpay()}
    }


    public static void Pay(string provider)
    {
        if(!providers.Containskey(provider))
            throw new InvalidOperationException("Invalid provider: " + provider);

        providers[provider].Pay();
    }

}

那么它的用法应该类似于PaymentHelper.Pay("paypal")

显然,如果要向Pay方法提供更多数据,则可以将其添加到接口和帮助器中。例如:

代码语言:javascript
复制
public interface IPaymentProvider
{
  void Pay(double amount);
}

public static void Pay(string provider, double amount)
{
    if(!providers.Containskey(provider))
        throw new InvalidOperationException("Invalid provider: " + provider);

    providers[provider].Pay(amount);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8879589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档