Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这就是多态性的例子吗?_C#_Polymorphism - Fatal编程技术网

C# 这就是多态性的例子吗?

C# 这就是多态性的例子吗?,c#,polymorphism,C#,Polymorphism,我有点知道多态性是什么,但没有弄清楚。我的代码如下: class Human { public virtual void CleanTheRoom() { } } class Woman:Human { public override void CleanTheRoom() { //women clean faster } } class Man:Human { public override void CleanTheRoom() {

我有点知道多态性是什么,但没有弄清楚。我的代码如下:

class Human
{
   public virtual void CleanTheRoom()
   {
   }
}
class Woman:Human
{
   public override void CleanTheRoom()
   {
     //women clean faster
   }
}
class Man:Human
{
   public override void CleanTheRoom()
   {
     //men clean slower, different code here
   }
}
class Child:Human
{
   public override void CleanTheRoom()
   {
     //empty ... children are lazy :)
   }
}

我是否应该解释这是多模态的,因为基类Human的所有派生类都包含方法CleanTheRoom,但每个派生类的实现都不同?

多态性的好处在于,当您想在某种类型的
Human
上调用方法
CleanTheRoom()
,但您不关心具体是哪一个

通过在基类级别定义
CleanTheRoom()
Human
,无论是
男人
女人
,还是
孩子
,只要使用
Human
,都可以在应用程序的其他地方编写更短、更干净的代码

例如,多态性允许您避免使用难看的条件语句,即显式检查每种类型的
Human
,并调用不同的方法:

好:

private void SomeMethod(Human h)
{
    //some logic
    h.CleanTheRoom();
    //more logic
}
private void SomeMethod(Human h)
{
    //some logic
    if (h is Man)
        CleanRoomSlowly();
    else if (h is Woman)
        CleanRoomQuickly();
    else if (h is Child)
        GoofOff();
    //some logic
}
坏:

private void SomeMethod(Human h)
{
    //some logic
    h.CleanTheRoom();
    //more logic
}
private void SomeMethod(Human h)
{
    //some logic
    if (h is Man)
        CleanRoomSlowly();
    else if (h is Woman)
        CleanRoomQuickly();
    else if (h is Child)
        GoofOff();
    //some logic
}

你所拥有的是一个继承的好例子。多态性是指能够通过使用单一类型(父类或接口)引用不同类型的对象,这种类型的继承使之成为可能。像这样:

List<Human> humans = new ArrayList<Human>();

humans.add(new Woman());
humans.add(new Woman());
humans.add(new Man());
humans.add(new Child());
humans.add(new Child());

foreach(Human hum in humans) {
   hum.CleanTheRoom(); //I don't know the type of hum, but I don't care
}
List humans=new ArrayList();
添加(新女性());
添加(新女性());
添加(newman());
添加(new Child());
添加(new Child());
foreach(人类的嗡嗡声){
哼哼。CleanTheRoom();//我不知道哼哼的类型,但我不在乎
}
假设我从不同的地方收集了人类的实例——我不知道每个实例是什么类型的。但我仍然可以遍历它们并调用CleanTheRoom(),因为它们共享一个父类


我将添加一个真实的示例。假设我有一个
Invoice
类,其中包含用于不同类型发票的不同子类——也许服务客户和一次性购买的客户有不同类型的
Invoice
s。有时候,我非常在意这些差异,我只处理一种类型的问题。但有时我想循环查看这个月的所有发票并打印出来。如果父类有一个
print()
方法(不同类型的实现方式可能不同),那么我可以这样做。

是的,这是正确的。您可以调用CleanTheRoom()方法,而不知道它是哪一类人


你有一些基本的例子。

我认为你没有看到好处,这是你完全理解多态性所缺少的关键。我将尝试举一个例子:

假设你有一个简单的积垢形式。这是“保存”按钮的代码:

var Client = PopulateDTO(); //put all the values in the controls, to an object

if(Action==Actions.Create){
  _repository.Create(Client);
}
else if(Action==Actions.Update){
  _repository.Update(Client);
}
else if(Action==Actions.Delete){
  _repository.Delete(Client);
}

this.Close();
这段代码可以工作,但它是糟糕的代码,很难阅读。让我们使用多态性(以及策略模式):

因此,我们有一个抽象类和3个实现,每个实现都在处理客户机对象。现在,表单中保存按钮的代码为:

BaseStrategy stg = GetCorrectStrategy();

var Client = PopulateDTO();

stg.Do(Client);

this.close;
方法GetCorrectStrategy()将实例化正确的策略实现,具体取决于用户是否正在创建、编辑或删除客户端


我希望这个答案能对你有所帮助。但如果没有帮助您,我建议您阅读有关策略模式的内容,在我看来,这是多态性的最佳用途之一

既然有几个人已经给出了多态性的好例子,我将提供一个真正帮助我探索它的不同视角

在函数式编程中,函数是第一类概念,而OOP中对象是最高的

多态性对于OOP就像模式匹配对于FP一样。下面是一个使用模式匹配(使用ML样式语法)的函数

因此,当您使用函数f时,可以向它传递类型为T、S、U或V的对象。在像f#这样的强类型FP语言中,x的类型表示为
T | S | U | V
。此类类型通常称为总和类型或标记的联合

如果我们修改您的示例,使
Human
成为一个抽象类,那么很明显,OOP中的多态性只是为您提供了一种表示求和类型的方法

因此,
CleanTheRoom
是一个类型为
Human
的函数。但是
Human
只是类型
Man | Woman | Child
的名称,这是一种总和类型。像C#这样的语言和像F#这样的函数式语言之间的最大区别在于,一种语言将对象视为顶级事物,而另一种语言将函数视为顶级事物。此外,像C#这样的OOP语言中的所有东西都必须有名称。在函数式语言中,我们可以表示类型
Man | Woman | Child
,而无需显式命名

关键不在于将代码视为具有不同的
CleanTheRoom
方法,而是将
CleanTheRoom
视为一种将类型
Man | Woman | Child
(名为
Human
)作为一种方法。多态性只是实现细节

总之,多态性(尤其是抽象类)基本上只提供了一种命名和类型并进行模式匹配的方法

见:

    • C#中的一个例子:

      这是我的班级档案

      class parent
          {
              public virtual string saySomething(string s)
              {
                  return s+":Parent";
              }
          }
          class man : parent
          {
              public override string saySomething(string s)
              {
                  return s+":Man";
              }
          }
          class woman : parent
          {
              public override string saySomething(string s)
              {
                  return s+":Woman";
              }
          }
          class child : parent
          {
              public override string saySomething(string s)
              {
                  return s+":Child";
              }
          }
      
      创建四个按钮和一个标签

      下面是一个简单表单1的实现

      private void Form1_Load(object sender, EventArgs e)
              {
                   p1= new parent();       
      
              }
      
              private void button1_Click(object sender, EventArgs e)
              {            
                  label1.Text = p1.saySomething("I am parent!");
              }
      
              private void button2_Click(object sender, EventArgs e)
              {
                  p1 = new man();
                  label1.Text = p1.saySomething("I am man!");
              }
      
              private void button3_Click(object sender, EventArgs e)
              {
                  p1 = new woman();
                  label1.Text = p1.saySomething("I am woman!");
              }
      
              private void button4_Click(object sender, EventArgs e)
              {
                  p1 = new child();
                  label1.Text = p1.saySomething("I am child!");
              }
      
      它是运行时多态性吗? P1是一个对象。根据情况(上下文),单击一个按钮,它将执行不同的代码段。因此,p1的行为因单击事件而异。

      类程序
      
      class Program
      {
          static void Main(string[] args)
          {
              List<ICleanTheRoom> cleanerList = new List<ICleanTheRoom>
                  {
                      new Child(), 
                      new Woman(), 
                      new Man()
                  };
              foreach (var cleaner in cleanerList)
              {
                  cleaner.CleanTheRoom();
              }
          }
      }
      
      internal interface ICleanTheRoom
      {
          void CleanTheRoom();
      }
      
      // No need for super type
      
      //class Human : ICleanTheRoom
      //{
      //   public virtual void CleanTheRoom()
      //   {
      //   }
      //}
      
      
      internal class Woman : ICleanTheRoom
      {
          public void CleanTheRoom()
          {
              throw new NotImplementedException();
          }
      }
      
      class Man: ICleanTheRoom
      {
          public void CleanTheRoom()
          {
              throw new NotImplementedException();
          }
      }
      
      class Child: ICleanTheRoom
      {
          public void CleanTheRoom()
          {
              throw new NotImplementedException();
          }
      }
      
      { 静态void Main(字符串[]参数) { List cleanerList=新列表 { 新的子对象(), 新女人(), 新人() }; foreach(cleanerList中的var cleaner) { 清洁工; } } } 内部接口 { 空置洁净室(); } //不需要超级类型 //类人:Icleartoom //{ //公共虚拟语音