使用C#,java或c ++ ...
我们有以下课程
class A
{
void x(){y();}
void y(){}
}
class B :A
{
void y(){};
void a(){x();}
}
//in main or somewhere
B b=new B();
b.a();
当调用函数“a”时,它将调用基数“x”函数 问题是,函数“x”将调用哪个函数(基数y()/派生y())? 我们如何控制哪一个调用!!
注意:采取这个概念,我知道三种语言不一样。
答案 0 :(得分:2)
(假设您打算将所有内容声明为公共内容,并为每种语言使用适当的语法)
在Java和C#中,它将调用B :: y。
在C ++中,它将调用A :: y。
在C ++中,如果您将A :: y声明为虚拟,则会调用B :: y。
实现静态分派(A :: y)比动态分派(B :: y)更高效,因此该选项在C ++中保持打开状态,以便在它们之间进行选择(虚拟或非虚拟)。对于Java和C#,语言设计者决定保持简单,只允许动态调度,因此这两种语言无法进行静态调度(A :: y)。
答案 1 :(得分:2)
您的代码无效C ++,但如果您说B * b = new B; b->a();
,则会调用A::y()
,因为它不是virtual
。在Java中,所有非静态成员函数都是隐式虚拟的,因此在那里调用B::y()
。
顺便说一下,你的问题非常具有误导性,因为“访问”是完全不同的(与public
和private
等有关)。就此而言,代码不会以任何语言编译,因为B::a()
不是public
。
答案 2 :(得分:2)
此代码示例将执行的操作非常依赖于您在此处使用的语言。你的问题在这里提到了C#/ C ++和Java,它们对于上面的基本模式会有所不同。
C#和C ++在这里非常相似,默认情况下函数不是虚拟的。因此,x()
中x()
的调用将引用A::x
。在Java中,虽然默认情况下方法是虚拟的,因此它将引用A::y
或B::y
,具体取决于this
的实际类型。
以下是使y()
成为虚拟调用的所有3种语言的示例
C ++
class A {
public:
void x(){ y(); }
virtual void y(){}
};
class B : public A {
public:
// virtual not needed here but nice
virtual void y() { };
void a() { x(); }
};
B* b = new B();
b->a();
C#
class A {
public void x(){ y(); }
public virtual void y(){}
}
class B : public A {
public overrides void y() { };
public void a() { x(); }
};
B b = new B();
b.a();
爪哇
class A {
public void x(){ y(); }
public void y(){}
}
class B : inherits A {
public void y() { };
public void a() { x(); }
};
B b = new B();
b.a();