C#与.net 多态 1
案例1:
想出这么个办法帮助新人理解多态。如果你能想出输出内容来,就理解多态了可以飘过了……;如果你不理解多态,理解了这个例子相信你会记一辈子。
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace ConsoleApplication2
- {
- class Program
- {
- static void Main(string[] args)
- {
- Bird b1 = new 公麻雀();
- b1.Fly();
- }
- }
- class Bird
- {
- public virtual void Fly() //通过虚函数实现
- {
- Console.WriteLine("Flying...");
- }
- }
- class 麻雀:Bird
- {
- public override void Fly() //重写、覆盖
- {
- Console.WriteLine("扑哧扑哧飞");
- }
- }
- class 公麻雀:麻雀
- {
- public virtual void Fly()
- {
- Console.WriteLine("挺着JJ飞。。。");
- }
- }
- }
输出内容:扑哧扑哧飞
(http://blog.csdn.net/szwang1/article/details/8663870)
我个人认为多态主要是三个特点:
1、重写(override)
2、通过虚函数实现
3、父类引用指向子类的对象
好吧,按我的理解,再简单点,不就是子类重写父类虚函数吗?!
一家之言,不当之处还望指教。
知道继承吧, 继承是属性的抽象, 多态是行为的抽象。
都是为了设计时,把繁杂的信息归类成简单的属性和行为。
就像在你们公司,不论是高管还是打扫卫生的,都有统一的行为, 干活和领工资,这就是行为的抽象。
虽然都是干活,每个角色干的活不一样。 虽然都领工资,但是每个角色计算工资的方式同样不同。
再详细看一下:
若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法。
虚方法与非虚方法的最大不同是,虚方法的实现可以由派生类所取代,这种取代是通过方法的重写实现的(以后再讲)
虚方法的特点:
虚方法前不允许有static,abstract,或override修饰符
虚方法不能是私有的,因此不能使用private修饰符
虚方法的执行:
我们知道一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,
而虚函数在编译期间是不被静态编译的,它的相对地址是不确定的,它会根据运行时期对象实例来动态判断要调用的函数,
其中那个申明时定义的类叫申明类,那个执行时实例化的类叫实例类。
如:A a =new B(); 其中A是申明类,B是实例类。
1.当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数;
2.如果不是虚函数,那么它就直接执行该函数。而如果是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是开始检查对象的实例类。
3.在这个实例类里,他会检查这个实例类的定义中是否有实现该虚函数或者重新实现该虚函数(通过override关键字)的方法,
如果有,它就不会再找了,而是马上执行该实例类中实现的虚函数的方法。而如果没有的话,系统就会不停地往上找实例类的父类,
并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。
例1:
class A
{
public virtual void Sum()
{
Console.WriteLine("I am A Class,I am virtual sum().");
}
}
class Program
{
static void Main(string[] args)
{
A a=new A(); // 定义一个a这个A类的对象.这个A就是a的申明类,实例化a对象,A是a的实例类
a.Sum();
Console.Read();
}
}
执行a.Sum:
1.先检查申明类A 2.检查到是sum是虚拟方法 3.转去检查实例类A,结果是题本身
4.执行实例类A中实现Sum的方法 5.输出结果 I am A Class,I am virtual sum().
例2:
class A
{
public virtual void Sum()
{
Console.WriteLine("I am A Class,I am virtual sum().");
}
}
class B : A
{
public override void Sum() // 重新实现了虚函数
{
Console.WriteLine("I am B Class,I am override sum().");
}
}
class Program
{
static void Main(string[] args)
{
A a=new B(); // 定义一个a这个A类的对象.这个A就是a的申明类,实例化a对象,B是a的实例类
a.Sum();
Console.Read();
}
}
执行a.Sum:
1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,有重写的方法 4.执行实例类B中的方法 5.输出结果 I am B Class,I am override sum().
例3:
class A
{
public virtual void Sum()
{
Console.WriteLine("I am A Class,I am virtual sum().");
}
}
class B : A
{
public override void Sum() // 重新实现了虚函数
{
Console.WriteLine("I am B Class,I am override sum().");
}
}
class C : B
{
}
class Program
{
static void Main(string[] args)
{
A a=new C();// 定义一个a这个A类的对象.这个A就是a的申明类,实例化a对象,C是a的实例类
a.Sum();
Console.Read();
}
}
执行a.Sum:
1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类C,无重写的方法 4.转去检查类C的父类B,有重写的方法
5.执行父类B中的Sum方法 6.输出结果 I am B Class,I am override sum().
例4:
class A
{
public virtual void Sum()
{
Console.WriteLine("I am A Class,I am virtual sum().");
}
}
class B : A
{
public new void Sum() //覆盖父类里的同名函数,而不是重新实现
{
Console.WriteLine("I am B Class,I am new sum().");
}
}
class Program
{
static void Main(string[] args)
{
A a=new B();
a.Sum();
Console.Read();
}
}
执行a.Sum:
1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,无重写的(这个地方要注意了,虽然B里有实现Sum(),但没有使用override关键字,所以不会被认为是重写) 4.转去检查类B的父类A,就为本身 5.执行父类A中的Sum方法 6.输出结果 I am A Class,I am virtual sum().
那么如果在例4里,申明的是类B呢?
class A
{
public virtual void Sum()
{
Console.WriteLine("I am A Class,I am virtual sum().");
}
}
class B : A
{
public new void Sum() //覆盖父类里的同名函数,而不是重新实现
{
Console.WriteLine("I am B Class,I am new sum().");
}
}
class Program
{
static void Main(string[] args)
{
B b=new B();
b.Sum();
Console.Read();
}
}
例5:
class A
{
public virtual void Sum()
{
Console.WriteLine("I am A Class,I am virtual sum().");
}
}
class B : A
{
public virtual void Sum()
{
Console.WriteLine("I am B Class,I am new sum().");
}
}
class C : B
{
public virtual void Sum()
{
Console.WriteLine("I am C Class,I am new sum().");
}
}
class Program
{
static void Main(string[] args)
{
A a=new C();
c.Sum(); //I am A Class,I am virtual sum()
Console.Read();
}
}
(http://blog.csdn.net/suncherrydream/article/details/8423991)
posted on 2016-01-07 11:09 springgao_2007 阅读(174) 评论(0) 收藏 举报

浙公网安备 33010602011771号