多重继承或缺乏 [英] Multiple Inheritance or lack therof

查看:91
本文介绍了多重继承或缺乏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道C#不允许多重继承。我开始了一个实践继承原则的项目,并将自己投入了一个角落。我对如何管理它有一些想法,但我不会再有任何继承了。基本上我有......



<前lang =c#> 员工
{
string 名称;
string soc;
十进制 hourly_rate;
...
}

class TaxInfo:员工
{
int FedEmemptions;
int StateExemptions;
bool 结婚;
...
}

class 工资单:TaxInfo
{
int 小时; // 在付款期内工作的小时数
bool direct_deposit; // 是否直接存款?
decimal TaxRate;
decimal gross_pay;
decimal net_pay;
}





我可以通过这种方式继承所有品质,但访问受限。我希望...



工资单p1 = 工资单(); 





...然后从p1访问所有继承的类。我现在意识到我不能这样做,除非我在中产阶级(TaxInfo)制作一些转发器代码......而且这只是马虎。



我有另一个想法,但我似乎没有看到它在C#中实践过,就像我在C中一样。让我知道你的想法,或者是否有更好的方法来实现它。



  class  TaxInfo 
{
int FedEmemptions;
int StateExemptions;
bool 结婚;
...
}

class 员工
{
string soc;
十进制 hourly_rate;
TaxInfo eTaxInfo;
...
}

class 薪资:员工
{
...
}





出于懒惰,我没有添加任何访问修饰符,但我知道其中一些应该是公开的或protected。

解决方案

您可能在成员上缺少'protected'这个词,这意味着它们在类及其所有子类型中都可见。



即便如此,这种继承感觉不对。 TaxInfo是Employee类型,还是Payroll类型是Employee / TaxInfo?组合可能是一个更好的主意,其中和员工包含这些东西而不是从中得出。


我认为你已经得出结论,你实现了有一个关系(工资单有一个员工列表;员工有一个TaxInfo) - 关系(通过继承)不是这个特定情况的正确模型。



但是,imho,复合或级联,继承(我称之为这种类型的建模)当然适用于其他情况。立即想到分类学:

王国:古细菌[935939] 
门:Crenarchaeota [951422]
类别:Aigarchaeota [951435]
类别:Korarchaeota [951424]
类别:Thaumarchaeota [951425]
顺序:Cenarchaeales [951439]
家庭:Cenarchaeaceae [951456]
属:Cenarchaeum

这断言Genar Cenarchaeum确实继承Archaea / Crenarchaeota / Thaumarchaeota / Cenarchaeles / Cenarchaeaceae的所有物业。



在我看来,您在薪资等级中显示的字段确实属于员工类别,'TaxRate将属于TaxInfo类。


缺乏多重继承的设计级解决方案是:



  1. 使用组合而不是从侧面继承。可以作为第二个基类的类型可以以此类的实例形式对派生类做出贡献,将其用作字段或属性。
  2. 使用接口。对于接口,允许多重继承;并且单个类可以实现多个接口(也就是说,它可以有多个基类型,但只能有一个基类)。它无助于消除重复的代码本身;所以,有时你可以使用 helper types 来多次在不同的类中实现接口。





规划继承/组合设计以避免重复代码可能非常困难;它需要良好的愿景和预测项目未来发展的能力。我必须注意,具有完全多重继承的系统也会导致需要解决的问题。以下是重要的例子:

http://en.wikipedia.org/wiki/Multiple_inheritance# The_diamond_problem [ ^ ],

http://en.wikipedia.org/wiki/Circle-ellipse_problem [ ^ ]。



-SA


I know C# does not allow multiple Inheritance. I started a project to practice the principals of inheritance and worked myself into a corner. I have some ideas on how to manage it, but I wouldn't really have any inheritance anymore. Basically I have...

class Employee
{
   string name;
   string soc;
   decimal hourly_rate;
   ...
}

class TaxInfo : Employee
{
   int FedEmemptions;
   int StateExemptions;
   bool married;
   ...
}

class Payroll : TaxInfo
{
   int hours;  // hours worked in the pay period
   bool direct_deposit;  //direct deposit or not?
   decimal TaxRate;
   decimal gross_pay;
   decimal net_pay;
}



I'm able to inherit all the qualities by doing this, but with limited access. I was hoping to...

Payroll p1 = new Payroll();



...and then access the inherited classes all from p1. I now realize I can't do this unless I make some "repeater" code in the middle class (TaxInfo)...and that's just sloppy.

I have another idea, but I don't seem to see it ever practiced in C# as I have in C. Let me know your thoughts, or if there's a better way to implement this.

class TaxInfo 
{
   int FedEmemptions;
   int StateExemptions;
   bool married;
   ...
}

class Employee
{
   string soc;
   decimal hourly_rate;
   TaxInfo eTaxInfo;
   ...
}

class Payroll : Employee
{
   ...
}



Out of laziness, I did not add any access modifiers, but I understand some of these should be public or protected.

解决方案

You probably are missing the word 'protected' on the members, meaning that they are visible in the class and all its subtypes.

Even so, this inheritance doesn't feel right. Is TaxInfo at type of Employee, or Payroll a type of Employee/TaxInfo? Composition might be a better idea, where and employee contains these things rather than deriving from them.


I think you've already come to the conclusion that your implementing "has-a" relationships (Payroll has-a List of Employee; Employee has-a TaxInfo) as is-a relationships (by inheritance) is not the right model for this particular case.

However, imho, compound, or cascading, inheritance (which is what I call this type of modelling) is certainly appropriate for other cases. Taxonomy immediately comes to mind:

Kingdom:  Archaea [935939] 
	Phylum:  Crenarchaeota [951422] 
		Class:  Aigarchaeota [951435] 
		Class:  Korarchaeota [951424] 
		Class:  Thaumarchaeota [951425] 
				Order:  Cenarchaeales [951439] 
						Family:  Cenarchaeaceae [951456] 
								Genus:  Cenarchaeum 

This asserts that Genus Cenarchaeum does inherit all properties from Archaea/Crenarchaeota/Thaumarchaeota/Cenarchaeles/Cenarchaeaceae.

It does seem to me that the Fields you show in the Payroll Class really belong in the Employee Class, and that 'TaxRate would belong in the TaxInfo Class.


The design-level work-around of the lack of multiple inheritance is:

  1. Using composition instead of inheritance from on of the side. The type which could be the second base class could contribute to the derived class in the form of the instance on this class uses as a field or a property.
  2. Using interfaces. For interfaces, multiple inheritance is allowed; and a single class can implement multiple interfaces (that is, it can have several base types, but only one base class). It does not help to eliminate repeated code itself; so, sometimes you can use helper types used to implement interfaces in different classes more than once.



It can be pretty difficult to plan your inheritance/composition design to avoid repetition of the code; it requires good vision and the ability to predict the future development of the project. I must note that the systems with full multiple inheritance also cause such problems which need to be worked around. These are the important examples:
http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem[^],
http://en.wikipedia.org/wiki/Circle-ellipse_problem[^].

—SA


这篇关于多重继承或缺乏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆