我有一个问题适用于所有使用静态类型和某种OOP的语言。
如果我有A类,B类是A的子类,C类是B的子类和A类变量,我可以在其中存储B和C的实例吗?
答案 0 :(得分:6)
在Delphi中,答案是肯定的。
例如,我创建了一个语法高亮的文本编辑器组件。此组件具有属性FormattingProcessor
,其类型为TFormattingProcessor
。现在,我创建了几个格式化处理器,例如TXMLFormattingProcessor
,TPascalFormattingProcessor
和TINIFormattingProcessor
,每个班级都是TFormattingProcessor
的孩子。其中任何一个都可以分配给文本编辑器组件的FormattingProcessor
属性。
也就是说,声明为TFormattingProcessor
的变量可以被赋予类型为TXMLFormattingProcessor
,TPascalFormattingProcessor
或TINIFormattingProcessor
的值。
如果您在VCL中查看,您会发现这种类型的分配实际上很常见。例如,TLabel
组件具有FocusControl
属性,其类型为TWinControl
(如果我没记错的话)。您可以将TWinControl
的任何后代分配给此属性,例如一个TEdit
。 (当使用Alt键同时键入标签的加速器字符时,FocusControl将获得键盘焦点。)
答案 1 :(得分:4)
在C ++中答案是否定的。如果类型为A*
或A&
,则答案为是,但仅A
则为否。
在Java,C#和其他语言中,默认情况下变量是对象的引用,答案是肯定的。
答案 2 :(得分:1)
当你说一个班级'B'是'A'的孩子并且正在进行访问时,如果不知道什么类型的继承是什么意思,这个问题就无法可靠地回答。换句话说,在不知道基数是否可访问和明确的情况下,无法正确回答这个问题。
$ 11.2 / 4 - “如果可以访问基类的发明公共成员,则可以访问基类。”
假设'A'是'B'的明确且可访问的基础,'B'是'C'的明确和可访问的基础,'A','B'和'C'是具体的类(没有纯虚函数)
B b;
C c;
A &rb = b; // OK
A &rc = c; // OK
A *pb = &b; // OK
A *pc = &c; // OK
A a1 = b; // sliced, only 'A' subobject of 'B' is copied onto 'a1', may be a logical error
A a2 = c; // sliced, only 'A' subobject of 'C' is copied onto 'a2', may be a logical error