为了账号安全,请及时绑定邮箱和手机立即绑定

C#应该具有多重继承吗?

C#应该具有多重继承吗?

C#
倚天杖 2019-11-14 08:56:46
我遇到了许多反对在C#中包含多重继承的论点,其中一些(除了哲学论点之外)包括:多重继承太复杂了,常常是模棱两可的不必要是因为接口提供了类似的东西在接口不合适的地方,组合是一个很好的替代品我来自C ++背景,错过了多重继承的强大功能。尽管它不适用于所有软件设计,但在某些情况下很难否认它在接口,组合和类似的OO技术上的实用性。排除多重继承是否意味着开发人员不够聪明,无法明智地使用它们,并且在它们出现时无法解决复杂性?我个人欢迎将多重继承引入C#(也许是C ##)。附录:我想从答复中了解谁来自单一(或程序背景)与多重继承背景。我经常发现,没有多重继承经验的开发人员经常会因为没有任何范例经验而默认使用“多重继承就是不必要”的论点。
查看完整描述

3 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

我从来没有错过任何一次,也从未错过。是的,它[MI]变得很复杂,是的,接口在许多方面都可以完成类似的工作-但这并不是最大的意义:从一般意义上讲,大部分时间根本不需要它。在许多情况下,甚至单一继承也被滥用。


查看完整回答
反对 回复 2019-11-14
?
白衣非少年

TA贡献1155条经验 获得超0个赞

优先考虑聚合而不是继承!


class foo : bar, baz

通常可以更好地处理


class foo : Ibarrable, Ibazzable

{

  ... 

  public Bar TheBar{ set }

  public Baz TheBaz{ set }


  public void BarFunction()

  {

     TheBar.doSomething();

  }

  public Thing BazFunction( object param )

  {

    return TheBaz.doSomethingComplex(param);

  }

}

这样,您可以交换IBarrable和IBazzable的不同实现,以创建应用程序的多个版本,而不必编写另一个类。


依赖注入可以对此提供很多帮助。


查看完整回答
反对 回复 2019-11-14
?
jeck猫

TA贡献1909条经验 获得超7个赞

处理多重继承的问题之一是接口继承与实现继承之间的区别。


通过使用纯接口,C#已经有了接口继承的干净实现(包括选择隐式或显式实现)。


如果你看一下C ++,对于每一个类,你在冒号后指定class的声明,那种继承你是通过访问修饰符确定(private,protected,或public)。有了public继承,您将获得多重继承的全部混乱—多个接口与多个实现混合在一起。使用private继承,您就可以实现。对象“ class Foo : private Bar”永远不会传递给需要a的函数,Bar因为好像Foo该类实际上只是具有一个私有Bar字段和一个自动实现的委派模式。


纯粹的多重实现继承(实际上只是自动委派)不会带来任何问题,并且在C#中非常棒。


对于从类继承多个接口,有许多不同的可能的设计用于实现该功能。对于在多个基类中以相同名称调用方法时发生的情况,每种具有多重继承的语言都有其自己的规则。某些语言,例如Common Lisp(特别是CLOS对象系统)和Python,都有元对象协议,您可以在其中指定基类的优先级。


这是一种可能性:


abstract class Gun

    public void Shoot(object target) {} 

    public void Shoot() {}


    public abstract void Reload();


    public void Cock() { Console.Write("Gun cocked."); }

}


class Camera

    public void Shoot(object subject) {}


    public virtual void Reload() {}


    public virtual void Focus() {}

}


//this is great for taking pictures of targets!

class PhotoPistol : Gun, Camera

    public override void Reload() { Console.Write("Gun reloaded."); }


    public override void Camera.Reload() { Console.Write("Camera reloaded."); }


    public override void Focus() {}

}


var    pp      = new PhotoPistol();

Gun    gun     = pp;

Camera camera  = pp;


pp.Shoot();                    //Gun.Shoot()

pp.Reload();                   //writes "Gun reloaded"

camera.Reload();               //writes "Camera reloaded"

pp.Cock();                     //writes "Gun cocked."

camera.Cock();                 //error: Camera.Cock() not found

((PhotoPistol) camera).Cock(); //writes "Gun cocked."

camera.Shoot();                //error:  Camera.Shoot() not found

((PhotoPistol) camera).Shoot();//Gun.Shoot()

pp.Shoot(target);              //Gun.Shoot(target)

camera.Shoot(target);          //Camera.Shoot(target)

在这种情况下,如果发生冲突,则仅隐式继承第一个列出的类的实现。必须明确指定其他基本类型的类才能实现其实现。为了使它更加防白痴,编译器可以在发生冲突的情况下禁止隐式继承(冲突的方法始终需要强制转换)。


另外,您现在可以使用隐式转换运算符在C#中实现多重继承:


public class PhotoPistol : Gun /* ,Camera */

{

    PhotoPistolCamera camera;


    public PhotoPistol() {

        camera = new PhotoPistolCamera();

    }


    public void Focus() { camera.Focus(); }


    class PhotoPistolCamera : Camera 

    { 

        public override Focus() { }

    }


    public static Camera implicit operator(PhotoPistol p) 

    { 

        return p.camera; 

    }

}

但是,它不是完美的,因为isand as运算符和不支持它System.Type.IsSubClassOf()。


查看完整回答
反对 回复 2019-11-14
  • 3 回答
  • 0 关注
  • 373 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信