c# – 有关转换和继承的乐趣

c# – 有关转换和继承的乐趣,第1张

概述注意:这个问题是用C#编写的伪代码,但我真的要问哪些语言有解决方案.请不要挂断语法. 说我有两个班: class AngleLabel: CustomLabel { public bool Bold; // Just upping the visibility to public // code to allow the label to be on an angle } 注意:这个问题是用C#编写的伪代码,但我真的要问哪些语言有解决方案.请不要挂断语法.

说我有两个班:

class AngleLabel: CustomLabel {     public bool Bold;  // Just upPing the visibility to public     // code to allow the label to be on an angle } class Label: CustomLabel {     public bool Bold;  // Just upPing the visibility to public     // Code for a normal label     // Maybe has code not in an AngleLabel (align for example). }

他们都脱离了这堂课:

class CustomLabel {     protected bool Bold; }

粗体字段在下属类中公开为公共字段.

这些类上没有可用的接口.

现在,我有一个方法,我希望能够传递CustomLabel并设置Bold属性.可以这样做而不必1)找出对象的真实类是什么,2)强制转换为该对象,然后3)为每个标签类型的每个变量制作单独的代码以设置粗体.有点像这样:

public voID SetBold(customLabel: CustomLabel) {     AngleLabel angleLabel;     normalLabel normalLabel;     if (angleLabel is AngleLabel )     {        angleLabel= customLabel as AngleLabel         angleLabel.Bold = true;     }     if (label is Label)     {        normalLabel = customLabel as Label        normalLabel .Bold = true;     } }

可能会做一个演员然后在一个变量上设置粗体会很好.

我正在思考的是创建第四个类,它只暴露粗体变量并将我的自定义标签投射到该类.

那会有用吗?

如果是这样,它会使用哪种语言? (此示例来自旧版本的Delphi(Delphi 5)).我不知道它是否适用于那种语言,(我仍然需要尝试一下)但我很好奇它是否适用于C,C#或Java.

如果没有,任何关于什么会有用的想法? (记住没有提供接口,我也无法修改类.)

有谁猜?

解决方法 它适用于Delphi.与其使用的类相同的单元中的代码具有对受保护(但不是严格受保护)成员的隐式访问权限,甚至是在另一个单元中声明的成员.您在CustomLabel中声明受保护的属性:

type  CustomLabel = class  private    FBold: Boolean;  protected    property Bold: Boolean read FBold write FBold;  end;

另一个单元中的粗体设置过程将拥有自己的CustomLabel后代:

type  TAccessCustomLabel = class(CustomLabel);procedure SetBold(customLabel: CustomLabel)begin  TAccessCustomLabel(customLabel).Bold := True;end;

您不能在其上使用as cast,因为实际参数永远不会是TAccessLabel的实例.它将是AngleLabel或normalLabel的一个实例,但由于所有三个类从CustomLabel继承的部分都是通用的,因此Bold属性在所有这些部分中都是相同的.即使在财产被公布或在后代发布之后,这仍然是正确的:

type  AngleLabel = class(CustomLabel)  public    property Bold;  end;

您可以更改属性的可见性,但不能更改字段.如果你对一个字段尝试相同的事情,你将声明一个具有隐藏继承字段的同名的新字段.

您可以在C中执行类似的 *** 作,但它并不像Delphi中那样常用,因此它可能会引起一些愤怒,特别是如果您打算编写可移植代码.

声明第四个类,就像在Delphi中一样.对于成员访问来说,C并不像Delphi那样松散,但它具有友谊的概念,在这种情况下也可以正常工作.

class AccessCustomLabel: public CustomLabel{  frIEnd voID SetLabel(CustomLabel* customLabel);};

该函数现在可以完全访问该类的成员:

voID SetLabel(CustomLabel* customLabel){  // Not allowed:  // customLabel->bold = true  // Not ordinarily allowed; requires frIEndship  reinterpret_cast<AccessCustomLabel*>(customLabel)->bold = true;}

这是技术上未定义的行为,因为我们已经将对象类型转换为它实际上没有的类型.我们依赖于CustomLabel的所有后代具有相同的布局,特别是对于AccessCustomLabel的粗体成员,它与任何其他CustomLabel后代的粗体成员位于相同的相对位置.

Delphi和C代码中的类型转换执行类型惩罚.你不会在C#或Java中侥幸逃脱;他们检查他们的演员表的结果,所以如果customLabel没有真正持有AccessCustomLabel的实例,你将得到一个例外.您必须使用反射来访问这些语言中不相关类的受保护成员.证明这超出了我的深度.

总结

以上是内存溢出为你收集整理的c# – 有关转换和继承的乐趣全部内容,希望文章能够帮你解决c# – 有关转换和继承的乐趣所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1222992.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存