C#中的多态
封装、继承、多态,面向对象的三大特性,前两项理解相对容易,但要理解多态,特别是深入的了解,对于初学者而言可能就会有一定困难了。我一直认为学习OO的最好方法就是结合实践,封装、继承在实际工作中的应用随处可见,但多态呢?也许未必,可能不经意间用到也不会把它跟“多态”这个词对应起来。在此抛砖引玉,大家讨论,个人能力有限,不足之处还请指正。
之前看到过类似的问题:如果面试时主考官要求你用一句话来描述多态,尽可能的精炼,你会怎么回答?当然答案有很多,每个人的理解和表达不尽相同,但我比较趋向这样描述:通过继承实现的不同对象调用相同的方法,表现出不同的行为,称之为多态。
1、一个简单的多态实现(参考自http://www.cnblogs.com/glacierh/):
2、如果继承中使用new而不是override关键字
3、多重继承
如果class A有一个virtual method(),class B继承于class A,并override method(),class C又继承于class B,那么class C是否可以继续override method()并实现多态呢?看下面的例子:
未完待续...
之前看到过类似的问题:如果面试时主考官要求你用一句话来描述多态,尽可能的精炼,你会怎么回答?当然答案有很多,每个人的理解和表达不尽相同,但我比较趋向这样描述:通过继承实现的不同对象调用相同的方法,表现出不同的行为,称之为多态。
1、一个简单的多态实现(参考自http://www.cnblogs.com/glacierh/):
public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal Eat ...");
}
}
public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat Eat ...");
}
}
public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog Eat ...");
}
}
class Program
{
static void Main(string[] args)
{
Animal[] animals = new Animal[3];
animals[0] = new Animal();
animals[1] = new Cat();
animals[2] = new Dog();
for (int i = 0; i < 3; i++)
{
animals[i].Eat();
}
}
}
输出结果:{
public virtual void Eat()
{
Console.WriteLine("Animal Eat ...");
}
}
public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat Eat ...");
}
}
public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog Eat ...");
}
}
class Program
{
static void Main(string[] args)
{
Animal[] animals = new Animal[3];
animals[0] = new Animal();
animals[1] = new Cat();
animals[2] = new Dog();
for (int i = 0; i < 3; i++)
{
animals[i].Eat();
}
}
}
Animal Eat ...
Cat Eat ...
Dog Eat ...
OK,从上面的例子可以看出,通过继承,使得Animal对象数组中的不同的对象,在调用Eat()方法时,表现出了不同的行为,这就是一个最简单的多态示例。Cat Eat ...
Dog Eat ...
2、如果继承中使用new而不是override关键字
public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal Eat ...");
}
}
public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat Eat ...");
}
}
public class Dog : Animal
{
//注意此处用了 new 而不再是 override 关键字
public new void Eat()
{
Console.WriteLine("Dog Eat ...");
}
}
class Program
{
static void Main(string[] args)
{
Animal animal = new Animal();
animal.Eat();
Animal cat = new Cat();
cat.Eat();
Animal dog = new Dog();
dog.Eat();
}
}
输出结果:{
public virtual void Eat()
{
Console.WriteLine("Animal Eat ...");
}
}
public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat Eat ...");
}
}
public class Dog : Animal
{
//注意此处用了 new 而不再是 override 关键字
public new void Eat()
{
Console.WriteLine("Dog Eat ...");
}
}
class Program
{
static void Main(string[] args)
{
Animal animal = new Animal();
animal.Eat();
Animal cat = new Cat();
cat.Eat();
Animal dog = new Dog();
dog.Eat();
}
}
Animal Eat ...
Cat Eat ...
Animal Eat ...
从结果中可以看出,当派生类Dog的Eat()方法使用new修饰时,Dog的对象转换为Animal对象后,调用的是Animal类中的Eat()方法。其实可以理解为,使用new关键字后,使得Dog中的Eat()方法和Animal中的Eat()方法成为毫不相关的两个方法,只是它们的名字碰巧相同而已。也由此可以看出:多态,依赖override实现。Cat Eat ...
Animal Eat ...
3、多重继承
如果class A有一个virtual method(),class B继承于class A,并override method(),class C又继承于class B,那么class C是否可以继续override method()并实现多态呢?看下面的例子:
public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal Eat ");
}
}
public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog Eat ");
}
}
public class WolfDog : Dog
{
public override void Eat()
{
Console.WriteLine("WolfDog Eat ");
}
}
class Program
{
static void Main(string[] args)
{
Animal animal = new Animal();
animal.Eat();
Animal dog = new Dog();
dog.Eat();
Animal wolfdog = new WolfDog();
wolfdog.Eat();
}
}
输出结果:{
public virtual void Eat()
{
Console.WriteLine("Animal Eat ");
}
}
public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog Eat ");
}
}
public class WolfDog : Dog
{
public override void Eat()
{
Console.WriteLine("WolfDog Eat ");
}
}
class Program
{
static void Main(string[] args)
{
Animal animal = new Animal();
animal.Eat();
Animal dog = new Dog();
dog.Eat();
Animal wolfdog = new WolfDog();
wolfdog.Eat();
}
}
Animal Eat ...
Dog Eat ...
WolfDog Eat ...
OK,现在得到了肯定的答案,不管继承关系包含了多少层,都可以在子类中对父类中已经重写的方法继续进行重写。即如果父类方法用override修饰,子类继承了该方法,同时也可以用override修饰,多重继承中的多态就是如此实现。要想终止这种重写,只需重写方法时使用sealed关键字。Dog Eat ...
WolfDog Eat ...
未完待续...