C# `as`会启用多态性吗?是否将继承的类传递给采用基类启用多态性的方法?
首先,我将使用C# `as`会启用多态性吗?是否将继承的类传递给采用基类启用多态性的方法?,c#,.net,polymorphism,as-operator,C#,.net,Polymorphism,As Operator,首先,我将使用virtual和override 例如,基类A有方法A.do(),继承的类B有覆盖A的方法B.do() 如果我调用(B作为A).do(),它将执行哪个do() 或者,如果有一个方法voidmymethod(aa){a.do()},现在我通过bb调用它;mymethod(b),它会执行b.do() 始终会调用最顶层的重写方法,即b.Do()或(b作为A.Do()或((A)b)。Do()将调用b.Do() 如果子类重写基类方法,我不知道如何从子类调用它。总是调用最顶层的重写方法,即b.
virtual
和override
例如,基类A有方法A.do()
,继承的类B有覆盖A的方法B.do()
如果我调用(B作为A).do()
,它将执行哪个do()
或者,如果有一个方法
voidmymethod(aa){a.do()}
,现在我通过bb调用它;mymethod(b)
,它会执行b.do()
始终会调用最顶层的重写方法,即b.Do()
或(b作为A.Do()
或((A)b)。Do()
将调用b.Do()
如果子类重写基类方法,我不知道如何从子类调用它。总是调用最顶层的重写方法,即
b.Do()
或(b作为a.Do()
或((a)b)。Do()
将调用b.Do()
public class A
{
public virtual void Do() { Console.Write("a"); }
public void Do2() { Console.Write("a2"); }
}
public class B : A
{
public override void Do() { Console.Write("b"); }
public new void Do2() { Console.Write("b2"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
A a = b;
b.Do(); //b
( b as A ).Do(); //b
a.Do(); //b
( (A)b ).Do(); //b
( b as A ).Do2(); //a2
( (A)b ).Do2(); //a2
( b ).Do2(); //b2
}
}
我不知道如果子类重写基类方法,如何从子类调用它
public class A
{
public virtual void Do() { Console.Write("a"); }
public void Do2() { Console.Write("a2"); }
}
public class B : A
{
public override void Do() { Console.Write("b"); }
public new void Do2() { Console.Write("b2"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
A a = b;
b.Do(); //b
( b as A ).Do(); //b
a.Do(); //b
( (A)b ).Do(); //b
( b as A ).Do2(); //a2
( (A)b ).Do2(); //a2
( b ).Do2(); //b2
}
}
输出:
b b b b
a2 a2 b2
输出:
b b b b
a2 a2 b2
这完全取决于do()方法是否声明为虚拟。如果它不是虚拟的,则调用A.do()。如果它是虚拟的,则调用B.do()。它是启用多态性并允许调用独立于引用类型的方法的虚拟关键字
C#中没有允许从B对象引用直接调用虚拟a.do()方法的机制。唯一的例外是在类B的实例方法中使用base.do()。这完全取决于do()方法是否声明为虚拟。如果它不是虚拟的,则调用A.do()。如果它是虚拟的,则调用B.do()。它是启用多态性并允许调用独立于引用类型的方法的虚拟关键字
public class A
{
public A() { }
public void Do() { Console.Write("A"); }
}
public class B : A
{
public B() { }
public void Do() { Console.Write("B"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
b.Do(); //<-- outputs B
(b as A).Do(); //<-- outputs A
}
}
C#中没有允许从B对象引用直接调用虚拟a.do()方法的机制。唯一的例外是在类B的实例方法中使用base.do()
public class A
{
public A() { }
public void Do() { Console.Write("A"); }
}
public class B : A
{
public B() { }
public void Do() { Console.Write("B"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
b.Do(); //<-- outputs B
(b as A).Do(); //<-- outputs A
}
}
重写方法时,调用B两次
当方法被重写时,调用B两次。让我用另一个问题回答您的问题:在测试此代码时调用了哪一个?顺便说一句,
as
操作符作用于对象实例,而不是像您的示例中那样作用于类型。似乎您希望显示多态性这不是覆盖而是隐藏。正是由于这个原因,您从编译器那里得到了一个警告。让我用另一个问题来回答您的问题:您测试此代码时调用了哪一个?顺便说一句,as
操作符作用于对象实例,而不是像您的示例中那样作用于类型。似乎您希望显示多态性这不是覆盖而是隐藏。正是由于这个原因,您从编译器那里得到了警告。实际上,它将调用B.Do()
,直到B:a
为止。您确定吗?当你建议某人运行代码时,也许你应该先运行它。@Nahum,abatishchev是正确的。无论您通过(-1)到达它的引用是如何声明的,动态分派都是有效的。没有什么好尴尬的。重要的是,您现在实际测试了代码并发布了正确的答案。这就是为社区带来价值的原因。我已经用赞成票代替了我的反对票,希望其他人也这样做。实际上它会调用B.do()
,直到B:A
你确定吗?当你建议某人运行代码时,也许你应该先运行它。@Nahum,abatishchev是正确的。无论您通过(-1)到达它的引用是如何声明的,动态分派都是有效的。没有什么好尴尬的。重要的是,您现在实际测试了代码并发布了正确的答案。这就是为社区带来价值的原因。我已经用赞成票代替了我的反对票,希望其他人也这样做。是的,我会重新编辑,所以要明确我走的是正确的多元主义道路。。虚拟+重写如果A.Do()
不是虚拟的,因此B.Do()
不会重写它,而是隐藏(带有适当的编译器警告)-那么B.Do()
无论如何都会被调用,不是吗?@abat-否,当对象引用是类型A时,会显式调用或通过强制转换调用.Do()。试试看:)是的,我会重新编辑,所以要明确我是用正确的方式进行多元文化。。虚拟+重写如果A.Do()
不是虚拟的,因此B.Do()
不会重写它,而是隐藏(带有适当的编译器警告)-那么B.Do()
无论如何都会被调用,不是吗?@abat-否,当对象引用是类型A时,会显式调用或通过强制转换调用.Do()。试试看:)sry,我想用virtual
和override
sry,我想用virtual
和override