简体   繁体   English

不使用virtual关键字的多态

[英]Polymorphism without using the virtual keyword

Obviously using virtual and override is the normal situation, but does this telecoms'ish example count? 显然,使用虚拟和替代是正常情况,但是这个电信示例是否有价值?

public class Pipe
{
  // whole bunch of protected member variables such as bandwidth, latency, download limit 
  // etc,

  public int GetCost()
  {
     // work out cost based on above
  }
}

public class BigFatPipe : Pipe
{
  public BigFatPipe()
  {
    // sets up the member variables one way
  }
}

public class CheapestPossiblePipe: Pipe
{
  public CheapestPossiblePipe()
  {
    // sets up the member variables another way
  }
}

then you might call 那你可能会打电话

PrintPrice(new BigFatPipe())

PrintPrice(new CheapestPossiblePipe())

public void PrintPrice(Pipe pipe)
{
   int a = pipe.GetCost();
   ....
}

You'll get two different answers. 您会得到两个不同的答案。 This isn't the most useful example but does it count? 这不是最有用的示例,但是它有用吗?

This post here has a useful discussion of what exactly polymorphism is. 这篇文章对确切的多态性进行了有用的讨论。

I think most definitions do not explicitly state that an object must have virtual functions to be polymorphic - so yes, I think your example counts. 我认为大多数定义都没有明确指出对象必须具有多态的虚函数-是的,我认为您的示例很重要。

Constructor overloading is a recognized method to implement static polymorphism. 构造函数重载是实现静态多态性的公认方法。 While this isn't really constructor overloading, it's close. 尽管这并不是真正的构造函数重载,但已经很接近了。 So yes, I'd call it polymorphism. 所以是的,我称之为多态性。

This pattern does work, but introducing a bunch of classes will confuse the user uselessly: they will wonder what the classes do differently. 这种模式确实有效,但是引入一堆类会使用户无用的困惑:他们会想知道这些类的不同之处。

A few factories methods will do the same job and will be easier to understand and maintain: 一些工厂方法可以完成相同的工作,并且更易于理解和维护:

public class Pipe
{
  // whole bunch of private member variables such as bandwidth, latency, download limit 
  // etc,

  public int GetCost()
  {
     // work out cost based on above
  }

  public static Pipe MakeBigFatPipe()
  {
      var result = new Pipe();
      // sets up the member variables one way
      return result;
  }

  public static Pipe MakeCheapestPossiblePipe()
  {
      var result = new Pipe();
      // sets up the member variables another way
      return result;
  }
}

If I were you I would use folowing approach: 如果我是你,我将使用以下方法:

public interface IGetCost
{
    int GetCost();
}

public class Pipe : IGetCost
{
    public int GetCost(){}
}

public class BigFatPipe : IGetCost
{
    //aggregation
    private readonly Pipe _pipe;

    public BigFatPipe(Pipe pipe)
    {
        _pipe = pipe;
    }
    public int GetCost() { }
}

public class CheapestPossiblePipe : IGetCost
{
    private readonly Pipe _pipe;

    public CheapestPossiblePipe(Pipe pipe)
    {
        _pipe = pipe;
    }
    public int GetCost() { }
}

public static void PrintPrice(IGetCost obj)
{
    int cost = obj.GetCost();
    Console.WriteLine(cost);
}

static void Main(string[] args)
{
    IGetCost p;

    p = new Pipe();
    PrintPrice(p);

    p = new BigFatPipe();
    PrintPrice(p);

    p = new CheapestPossiblePipe();
    PrintPrice(p);
}

I also need to say that there're two different things - polymorphism and overloading 我还需要说的是,有两种不同的东西-多态和重载

polymorphism 多态性

public class foo
{
    public virtual void foo1{/*....*/}
}

public class fooA : foo
{
    public override void foo1{/*....*/}
}

public class fooB : foo
{
    public new void foo1{/*....*/}
}

public class fooC : foo
{
    //new is the default modifier
    public void foo1{/*....*/}
}

overloading 超载

public class foo{
    public int foo1{/*....*/}
    public int foo1(int a){/*....*/}
    public int foo1(string a){/*....*/}
    public int foo1(int a, string b){/*....*/}
}

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

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