父类与子类相互转换
1 ///2 /// 动物类(父类) 3 /// 4 class Animal 5 { 6 public string Name { get; set; }//名字 7 public string Color { get; set; }//颜色 8 public string Kind { get; set; }//种类 9 public string Favorite { get; set; }//喜好10 11 public Animal() { }12 public Animal(string name, string color, string kind)13 {14 this.Name = name; 15 this.Color = color;16 this.Kind = kind;17 }18 //自我介绍19 public void Introduce()20 {21 string info = string.Format("我是漂亮的{0},我的名字叫{1},身穿{2}的衣服,我爱吃{3}!", this.Kind, Name, Color, Favorite);22 Console.WriteLine(info);23 }24 }
给Cat和Dog分别添加Have()方法:
1 ///2 /// 玩具猫类 3 /// 4 class Cat:Animal//继承Animal类 5 { 6 public Cat() { }//默认调用父类的无参构造函数,若此时父类并没有无参构造函数,则报错 7 public Cat(string name, string color, string kind, string favorite) : base(name, color, kind) 8 { 9 this.Favorite = favorite;10 }11 //跳舞12 public void Dancing()13 {14 base.Introduce();//调用父类的方法15 Console.WriteLine("下面给大家表演,请大家鼓掌!");16 }17 18 public void Have()19 {20 Console.WriteLine("吃烤鱼!");21 }
1 ///2 /// 玩具狗类 3 /// 4 class Dog:Animal//继承Animal类 5 { 6 public Dog(string name, string color, string kind) 7 { 8 this.Name = name;//使用this关键字访问父类成员 9 this.Color = color;10 this.Kind = kind;11 }12 13 public Dog() { }//隐式调用:默认调用父类的无参构造函数,若此时父类并没有无参构造函数,则出错。14 15 public Dog(string name, string color, string kind, string favorite) : base(name, color, kind)16 { //显示调用17 this.Favorite = favorite;18 }19 public void Race()20 {21 base.Introduce();//使用base关键字调用父类方法22 Console.WriteLine("下面给大家表演赛跑,请大家鼓掌!");23 }24 25 public override void Have()26 {27 Console.WriteLine("吃骨头!");28 }29 }
调用:
1 static void Main(string[] args) 2 { 3 //创建两个对象 4 Cat objCat = new Cat("球球", "黄色", "小花猫", "小鱼"); 5 Dog objDog = new Dog("团团", "黑色", "小黑狗", "骨头"); 6 7 //将子类对象添加到父类集合 8 Listlist = new List (); 9 10 //List
从上述代码示例中我们可以看到,父类类型可以添加子类对象,子类自动转换成父类类型。而在取出对象时,需要判断对象的原始类型属于哪一个对象,然后强制转换成对应子类对象,才能调用子类的方法。下面介绍如何使用抽象类和抽象方法优化上述示例代码。
使用抽象类和抽象方法
在父类中定义一个抽象方法:
1 ///2 /// 动物类(父类) 3 /// 4 abstract class Animal 5 { 6 public string Name { get; set; }//名字 7 public string Color { get; set; }//颜色 8 public string Kind { get; set; }//种类 9 public string Favorite { get; set; }//喜好10 11 public Animal() { }12 public Animal(string name, string color, string kind)13 {14 this.Name = name; 15 this.Color = color;16 this.Kind = kind;17 }18 //自我介绍19 public void Introduce()20 {21 string info = string.Format("我是漂亮的{0},我的名字叫{1},身穿{2}的衣服,我爱吃{3}!", this.Kind, Name, Color, Favorite);22 Console.WriteLine(info);23 }24 25 ///26 /// 定义一个抽象方法27 /// 28 public abstract void Have();
在子类中重写(override)父类未实现的方法(抽象方法):
1 ///2 /// 玩具猫类 3 /// 4 class Cat:Animal//继承Animal类 5 { 6 public Cat() { }//默认调用父类的无参构造函数,若此时父类并没有无参构造函数,则报错 7 public Cat(string name, string color, string kind, string favorite) : base(name, color, kind) 8 { 9 this.Favorite = favorite;10 }11 //跳舞12 public void Dancing()13 {14 base.Introduce();//调用父类的方法15 Console.WriteLine("下面给大家表演,请大家鼓掌!");16 }17 18 ///19 /// 重写父类的Have()方法20 /// 21 public override void Have()22 {23 Console.WriteLine("吃烤鱼!");24 }25 26 }
1 ///2 /// 玩具狗类 3 /// 4 class Dog:Animal//继承Animal类 5 { 6 public Dog(string name, string color, string kind) 7 { 8 this.Name = name;//使用this关键字访问父类成员 9 this.Color = color;10 this.Kind = kind;11 }12 13 public Dog() { }//隐式调用:默认调用父类的无参构造函数,若此时父类并没有无参构造函数,则出错。14 15 public Dog(string name, string color, string kind, string favorite) : base(name, color, kind)16 { //显示调用17 this.Favorite = favorite;18 }19 public void Race()20 {21 base.Introduce();//使用base关键字调用父类方法22 Console.WriteLine("下面给大家表演赛跑,请大家鼓掌!");23 }24 25 ///26 /// 重写父类的Have()方法27 /// 28 public override void Have()29 {30 Console.WriteLine("吃骨头!");31 }32 }
调用:
1 static void Main(string[] args) 2 { 3 //创建两个对象 4 Cat objCat = new Cat("球球", "黄色", "小花猫", "小鱼"); 5 Dog objDog = new Dog("团团", "黑色", "小黑狗", "骨头"); 6 7 //将子类对象添加到父类集合 8 Listlist = new List (); 9 10 //添加时自动将子类转换为父类类型11 list.Add(objCat);12 list.Add(objDog);13 14 //取出对象15 foreach (Animal obj in list)16 {17 obj.Have();//不再需要类型判断18 }19 20 }
使用抽象类和抽象方法后,我们发现无需对取出对象进行类型判断,程序也能自动调用对应子类的实现方法(由虚拟机完成)。充分体现了面向对象编程的"多态"思想,使用"继承多态"机制很好地解决了系统扩展问题。
总结抽象类与抽象方法
抽象类的概念与使用要点:
1.使用关键字abstract修饰的类,称为抽象类。
2.抽象类只是用来列举一个类所具有的行为,不能单独通过创建对象来使用,如 Animal animal=new Animal() (×)。
3.抽象类中可以有抽象方法,也可以没有任何抽象方法。但是有抽象方法的类一定是抽象类。
4.抽象类不能是静态类(static)或密封类(sealed)。注:密封类不能被重写。
抽象方法的概念与使用要点:
1.再抽象类中使用abstract修饰的方法,称之为抽象方法。
2.抽象方法必须再抽象类中定义,不能再普通类中使用(即有抽象方法的类一定是抽象类)。
3.抽象方法只是一个方法的声明,不能有任何方法体。如:public abstract void Have();
4.抽象方法仅仅表示一个应该具有的行为,具体实现由子类实现。
5.抽象方法再子类中被实现(重写)必须使用关键字override。
6.子类必须重写父类的所有抽象方法,除非子类本身也是抽象类。