On 12 Apr, 13:40, "David Zha0" <zhpl...@163.comwrote:
Hi,
"when we call a virtual method, the runtime will check the instance who
called the method and then choose the suitable override method, this may
causes the performance drop down", is this right?
And, why not use "new" instead of using "virtual"?
And the last question, what is the differences between a abstract method and
a interface?
Thanks.
Hi,
I'll work backwards as it will make more sense that way:
An interface is commonly considered a contract. If you have an
interface:
public interface AnInterface
{
void foo2();
void foo3();
}
Any class that implements that interface must provide an
implementation for all the elements (methods etc). All those methods
will be public (within the scope of the class of course)
public class ImplementationTest : AnInterface
{
public void foo()
{
}
void AnInterface.foo2()
{
}
}
Notice the foo is declared as public and foo2 is prefixed with the
interface name and a dot?
If we instantiate ImplementationTest you will be able to use foo
immediately, but not foo2. To get to foo2 you would need to cast to
the interface or assign it to an interface variable as follows.
ementationTest();
AnInterface second = first;
first.foo();
//first.foo2(); - can't see it!
second.foo(); // same as doing first.foo();
second.foo2(); //now we can see it!
Ok, so that's interfaces, lets look at abstract classes. An abstract
class is meant to be a template for a class. You can't instantiate
them, you can derive a class from it though and assign any derived
type to the a variable of the abstract class.
public abstract class AbstractClass
{
public abstract void fii();
protected abstract void fii2();
}
The first thing you can see is we have a public and protected method,
you can't do that with an interface. Here's a class that inherits from
Abstract class and does something.
public class Derived1 : AbstractClass
{
public override void fii()
{
Console.WriteLine("1.fii");
}
protected override void fii2()
{
Console.WriteLine("1.fii2");
}
}
To use we instantiate it and can optionally assign it to an
AbstractClass variable. It makes no odds at this point, but will
shortly.
Derived1 d1 = new Derived1();
AbstractClass a1 = d1;
a1.fii();
d1.fii();
Abstract classes can also implement interfaces and contain actual
working code. Lets add to the above:
public abstract class AbstractClass : AnInterface
{
public abstract void fii();
protected abstract void fii2();
public abstract void foo();
void AnInterface.foo2()
{
}
public void PublicMethod()
{
Console.WriteLine("PublicMethod");
}
}
First you'll notice foo and foo2 from our interface earlier. foo2 will
look familiar, foo however now has the abstract keyword meaning we can
provide an implementation of it in our derived class. foo2 will not
appear in our derived class.
Next notice PublicMethod. It's not abstract and not virtual. Don't
worry about virtual, we'll get to that shortly. As it isn't abstract.
Lets see it in action.
Derived1 d1 = new Derived1();
AbstractClass a1 = d1;
AnInterface i1 = d1;
d1.PublicMethod(); // works! Implementation is in AbstractClass
i1.foo2(); //works! implementation is in AbstractClass
d1.foo(); //works! implementation in Derived1
So as you can see our derived class now implements AnInterface but
only contains half the code, sharing the work with AbstractClass.
AbstractClass is also providing PublicMethod free of choice. If we
write Derived2,3,4,5, they will all get access to PublicMethod.
Now lets look at virtual and show another facet of derived classes
(whether from an abstract or non abstract base class).
public class AClass
{
public virtual void fee()
{
Console.WriteLine("2.fee");
}
public virtual void fee2()
{
Console.WriteLine("2.fee2");
}
}
virtual simply means if I derive a new class from this one I may
override it. This means that when you mark a method as abstract you
are also saying it is virtual.
public class AClass2 : AClass
{
public override void fee()
{
Console.WriteLine("AClass2.fee");
base.fee ();
}
public new void fee2()
{
Console.WriteLine("AClass2.fee2");
base.fee2();
}
}
And some test code.
AClass a1 = new AClass();
AClass2 a2 = new AClass2();
AClass a3 = a2;
Lets look at the output to see what the differences are. To recap,
AClass is the base class, AClass2 is the derived class. fee is
overriden, fee2 is overriden with the new keyword instead. Incidently
the derived methods call the base class's implementation of the method
after doing their own work. That's what base.method() does. So AClass2
is calling code in AClass.
Here's the test code with what gets printed.
a1.fee(); //fee on base class
a1.fee2(); //fee2 on base class
AClass.fee
AClass.fee2
So as expected it simply prints whats in the methods.
----
a2.fee(); //derived class
a2.fee2(); //derived class
AClass2.fee
AClass.fee
AClass2.fee2
AClass.fee2
More interesting, they print their message and then call AClass so we
get two lines of output for each line of code.
----
a3.fee(); //Base class variable holding reference to derived class
a3.fee2(); //Base class variable holding reference to derived class
AClass2.fee
AClass.fee
AClass.fee2
Three lines? fee was overriden with the override keyword, this means
it overrides the base class even if it's a base class variable.
fee2 was overriden with the new keyword, so when we give an AClass
variable a reference to an AClass2 instance AClass is free to use it's
own implementation.
Hope that helps.