说我有两个班:
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# – 有关转换和继承的乐趣所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)