第二十二节 多态性、抽象类多态、抽象类abstract
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
案例1:多态性 namespace e1 { class Person { } class Student:Person{} class Teacher:Person{} //多态性:含于(has a ) ; 属于(is a ) class Program { static void Main(string[] args) { /*一个基类的引用符,可以指向多种派生类对象,具有多种不同的形象,这个现象叫做多态性(Polymorphism)*/ Person p1 = new Student(); Person p2 = new Teacher(); } } } —————————————————————————————————————————————————— 案例2 扩展性 namespace e2 { public enum Genders{Maal,Female} class Person { protected string name; protected int age; protected Genders genders; public Person(string name, int age, Genders genders) { this.name = name; this.age = age; this.genders = genders; } } class Student:Person { private string hobby; public Student(string name,int age,Genders genders,string hobby) :base(name,age,genders) { this.hobby = hobby; } public void SayHi() { Console.WriteLine("姓名:{0},年龄:{1},性别:{2},爱好:{3}",name,age,genders,hobby); } } class Teacher:Person { private decimal salary; public Teacher(string name, int age, Genders genders, decimal salary) : base(name, age, genders) { this.salary = salary; } public void SayHi() { Console.WriteLine("姓名:{0},年龄:{1},性别:{2},工资:{3}",name,age,genders,salary); } } class Program { static void Main(string[] args) { Person[] person = new Person[2]; person[0] = new Teacher("张三", 18, Genders.Maal, 5000); person[1] = new Student("李四", 20, Genders.Female, "桌球"); //扩展的麻烦:假设我要添加班主任类,校长类,添加到该数组中, //在以下的foreach循环中又要对班主任类,校长类进行类型判断 //扩展性非常差,为了提高程序的扩展性,我们可以使用多态的方式来解决 foreach (Person p in person) { if(p is Student) { Student stu=(Student)p; stu.SayHi(); } else if(p is Teacher) { Teacher tea=(Teacher)p; tea.SayHi(); } } Console.ReadKey(); } } } —————————————————————————————————————— 案例3 抽象类多态 namespace e3 { public enum Genders{Maal,Female} abstract class Person { protected string name; protected int age; protected Genders genders; public Person(string name, int age, Genders genders) { this.name = name; this.age = age; this.genders = genders; } //一旦定义了抽象方法,就约束了我的子类必须实现(重写)父类中的这个抽象的方法 //除非子类中的这个方法也是抽象的 public abstract void SayHi(); } class Student:Person { private string hobby; public Student(string name,int age,Genders genders,string hobby) :base(name,age,genders) { this.hobby = hobby; } public override void SayHi() { Console.WriteLine("姓名:{0},年龄:{1},性别:{2},爱好:{3}", name, age, genders, hobby); } } class Teacher:Person { private decimal salary; public Teacher(string name, int age, Genders genders, decimal salary) : base(name, age, genders) { this.salary = salary; } public override void SayHi() { Console.WriteLine("姓名:{0},年龄:{1},性别:{2},工资:{3}", name, age, genders, salary); } } //抽象类不能定义给静态类(static)或者密封(sealed)类,C#中语法不被允许 //abstract static class Personq //{ //} class Program { static void Main(string[] args) { //抽象类不能被实例化 //可以将实现它的子类赋给抽象类引用 Person[] person = new Person[2]; person[0] = new Teacher("张三", 18, Genders.Maal, 8000); person[1] = new Student("李四", 29, Genders.Female, "桌球"); //抽象类:abstract ,重写:override //使用抽象类实现多态,提高了程序的可扩展性,我们无需判断父类中 //存在的具体数据是什么类型,他会根据你的具体存放的类型来掉用相应的方法 foreach (Person p in person) { p.SayHi(); } //泛型集合 //List<Person> list = new List<Person>(); //list.Add(new Student("李四", 29, Genders.Female, "桌球")); //list.Add(new Teacher("张三", 18, Genders.Maal, 8000)); //foreach (Person p in list) //{ // p.SayHi(); //} Console.ReadKey(); } } } —————————————————————————————————————————————————— 案例4: namespace e4 { abstract class Animal { public abstract void SayHi(); } class Cat : Animal { public override void SayHi() { Console.WriteLine("猫咪喵喵叫.........."); } } class Dog : Animal { public override void SayHi() { Console.WriteLine("狗会汪汪的叫............."); } } class Frog : Animal { public override void SayHi() { Console.WriteLine("青蛙呱呱的叫............."); } } class Program { static void Main(string[] args) { //多态(Polymorphism):不同对象收到相同的信息是,会产生不同行为 //Cat、Dog、Frog对象收到相同的调用信息,产生了他们各自的行为 List<Animal> list = new List<Animal>(); list.Add(new Cat()); list.Add(new Dog()); list.Add(new Frog()); foreach (Animal ani in list) { ani.SayHi(); } Console.ReadKey(); } } } ———————————————————————————— 案例5 操作符 is, as namespace e5 { class Person { } class Student : Person { } class Teacher : Person { } class Program { static void Main(string[] args) { //is操作符用于判断某个对象是什么类型,返回布尔值 Person p1 = new Student(); Console.WriteLine(p1 is Student); Console.WriteLine(p1 is Teacher); //强制转换 Student stu2 = p1 as Student; //强制转换:一旦转换不了就会报无效的数据转换异常,程序就会中断 //Teacher tea = (Teacher)p1; //as操作符,用于引用类型的数据类型转换 Student stu = (Student)p1; //as操作符:一旦转换不了就会返回一个null,那么我们可以根据它的返回值来判断 //是否数据类型转换成功,不会发生异常,不会中断 Teacher tea = p1 as Teacher; if (tea==null) { Console.WriteLine("无法进行转换数据类型转换....."); } Console.ReadKey(); } } } —————————————————————————— 案例6 namespace e6 { abstract class Cut { public abstract void SayHi(); } class Barber : Cut { public override void SayHi() { Console.WriteLine("剪短头发........."); } } class Doctor:Cut { public override void SayHi() { Console.WriteLine("切开皮肤......."); } } class Player:Cut { public override void SayHi() { Console.WriteLine("停在表演........."); } } class Program { static void Main(string[] args) { List<Cut> lc=new List<Cut>(); lc.Add(new Barber()); lc.Add(new Doctor()); lc.Add(new Player()); foreach (Cut C in lc) { C.SayHi(); } Console.ReadKey(); } } }