C#多态性详解
来源:互联网 发布:mac系统 matlab 2016b 编辑:程序博客网 时间:2024/06/18 12:06
文章部分内容来自:作者:Kevin 出处:http://zhangkai2237.cnblogs.com/
- 方法名必须相同
- 参数列表必须不相同
- 返回值类型可以不相同
public void Sleep() { Console.WriteLine("Animal睡觉"); } public int Sleep(int time) { Console.WriteLine("Animal{0}点睡觉", time); return time; }
- 相同的方法名
- 相同的参数列表
- 相同的返回值。
public virtual void EatFood() { Console.WriteLine("Animal吃东西"); }
子类中的定义:
public override void EatFood() { Console.WriteLine("Cat吃东西"); //base.EatFood(); }
tips:经常有童鞋问重载和重写的区别,而且网络上把这两个的区别作为C#做常考的面试题之一。实际上这两个概念完全没有关系,仅仅都带有一个“重”字。他们没有在一起比较的意义,仅仅分辨它们不同的定义就好了。
public virtual void EatFood() { Console.WriteLine("Animal吃东西"); }
Animal a = new Animal(); a.EatFood();
public abstract class Biology { public abstract void Live(); } public class Animal : Biology { public override void Live() { Console.WriteLine("Animal重写的抽象方法"); //throw new NotImplementedException(); } }
public void Sleep() { Console.WriteLine("Animal Sleep"); }
new public void Sleep() { Console.WriteLine("Cat Sleep"); }
或者为:public new void Sleep() { Console.WriteLine("Cat Sleep"); }
public abstract class Biology { public abstract void Live(); } public class Animal : Biology { public override void Live() { Console.WriteLine("Animal重写的Live"); //throw new NotImplementedException(); } public void Sleep() { Console.WriteLine("Animal Sleep"); } public int Sleep(int time) { Console.WriteLine("Animal在{0}点Sleep", time); return time; } public virtual void EatFood() { Console.WriteLine("Animal EatFood"); } } public class Cat : Animal { public override void EatFood() { Console.WriteLine("Cat EatFood"); //base.EatFood(); } new public void Sleep() { Console.WriteLine("Cat Sleep"); } //public new void Sleep() //{ // Console.WriteLine("Cat Sleep"); //} } public class Dog : Animal { public override void EatFood() { Console.WriteLine("Dog EatFood"); //base.EatFood(); } }
class Program { static void Main(string[] args) { //Animal的实例 Animal a = new Animal(); //Animal的实例,引用派生类Cat对象 Animal ac = new Cat(); //Animal的实例,引用派生类Dog对象 Animal ad = new Dog(); //Cat的实例 Cat c = new Cat(); //Dog的实例 Dog d = new Dog(); //重载 a.Sleep(); a.Sleep(23); //重写和虚方法 a.EatFood(); ac.EatFood(); ad.EatFood(); //抽象方法 a.Live(); //隐藏方法 a.Sleep(); ac.Sleep(); c.Sleep(); Console.ReadKey(); } }
//重载 a.Sleep(); a.Sleep(23);
//重写和虚方法 a.EatFood(); ac.EatFood(); ad.EatFood();
//抽象方法 a.Live();
//隐藏方法 a.Sleep(); ac.Sleep(); c.Sleep();
把动物“吃”的方法放到一个接口(IAnimal)里,然后让具体的动物类(Wolf/Sheep)继承这个接口,并根据自己的需要实现这个接口。
代码实现:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
}
}
public class Wolf : IAnimal {
//多态实现
public void Eat() {
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : IAnimal {
//多态实现
public void Eat() {
Console.WriteLine("羊吃草!");
}
}
//接口
public interface IAnimal {
void Eat();
}
接口的多态性就是当不同的类继承了相同的接口以后,都要根据自己的需要重新实现继承的接口,这样同样的方法签名在不同的类中就会实现不同的操作。
三、继承的多态性2.1.通过虚拟方法实现的多态(virtual,override)
首先要在基类中实现virtual方法,然后在派生类中根据自己的需要用override重写virtual方法。如果不希望这个方法被继续重写,则把这个方法写成sealed方法。
virtual方法必须在基类中实现。
代码实现:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
new Goat().Eat();
}
}
public class Wolf : Animal {
//多态实现
public override void Eat() {
base.Eat();
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : Animal {
//多态实现
public override void Eat() {
base.Eat();
Console.WriteLine("羊吃草!");
}
}
public class Goat : Sheep {
//多态实现被终结,此Eat方法不能被override,因为用sealed了
public sealed override void Eat() {
//base.Eat();
Console.WriteLine("山羊吃草!");
}
}
//基类实现虚方法
public class Animal {
public virtual void Eat() { }
}
2.2.通过抽象方法实现的多态(abstract,override)
抽象方法必须定义在抽象类里。抽象类不能被创建实例。
基类中的抽象方法只能被声明,不需要实现,所以派生类中重写抽象方法的时候没有base方法。
代码实现如下:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
new Goat().Eat();
}
}
public class Wolf : Animal {
//多态实现
public override void Eat() {
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : Animal {
//多态实现
public override void Eat() {
Console.WriteLine("羊吃草!");
}
}
public class Goat : Sheep {
//多态实现被终结,此Eat方法不能被override,因为用sealed了
public sealed override void Eat() {
Console.WriteLine("山羊吃草!");
}
}
//基类只需声明方法
public abstract class Animal {
public abstract void Eat();
}
四、总结:
1.虚方法重写的时候可以有base方法(base.Eat()),抽象方法重写的时候没有base方法,原因是:虚方法必须在基类中实现,抽象方法只在基类中声明,不需要实现。
2.派生类中可以 不重写虚方法的实现,但是派生类必须重写抽象方法的实现,原因同1.
3.包含虚方法的非抽象类可以被创建实例(对象),但是包含抽象方法的抽象类不能被创建实例。
4.继承接口的派生类必须实现接口的方法,因为接口也是只负责声明方法,不负责实现。
5.接口的多态性不需要用override重写方法。
- C#多态性详解
- c#学习笔记六 多态性详解
- C#多态性
- C#多态性
- c# 多态性
- c# 多态性
- c# 多态性
- C#多态性
- c# 多态性
- C# 多态性
- C#多态性
- C#多态性
- C# 多态性
- C# 多态性
- C# 多态性
- 多态性C#
- C# 多态性
- C# 多态性
- 全球主要气象气候研究部门及其共享数据集介绍
- 动态规划_拦截导弹
- MongoDB之备份与恢复
- ACM经典算法之排序/查找
- Windows I/O系统
- C#多态性详解
- DeepID算法实践
- Unity 2D入门基础教程
- uva 11292The Dragon of Loowater
- 再谈WDK环境配置
- Hadoop导航:版本、生态圈及MapReduce模型
- iOS调起微信,qq,支付宝app支付总结
- 非常难得的iPad版房地产售楼助手应用源码项目
- 线程同步与互斥:读写锁