--------------------- ASP.Net+Android+IOS开发.Net培训期待与您交流! ----------------------
■子类可以有与父类方法名相同的方法
♢签名不同(重载)
♢签名相同(隐藏基类方法)
■子类可以重写父类方法
♢虚方法
♢重写方法
♢重写基类方法一样可以调用基类方法
■多态就是对象可以表现多个类型的能力.(一种表现形式,实现多种功能)
■几种建立多态的方式
♢用父类实现多态
♢用抽象类实现多态
♢用接口实现多态
■多态版本控制
♢需要保留基类方法使用new关键字
♢需要重写方法使用override关键字
1.隐藏基类方法
class Program { static void Main(string[] args) { Base b = new Base(); b.Func();//结果:我是一个父类 Sub s = new Sub(); s.Func();//结果:我是一个子类,此处隐藏了基类的方法 Base b1 = s; b1.Func();//结果:我是一个父类 Console.ReadKey(); } } class Base { public void Func() { Console.WriteLine("我是一个父类"); } } class Sub : Base { public new void Func()//此处可以直接写成 public void Func()省略掉new,我们姑且称为隐式隐藏 { Console.WriteLine("我是一个子类"); } }
通过上述例子,我们得知:隐藏基类方法时,我们访问到的方法是依据引用变量的,引用变量是基类访问到的就是基类的方法,引用变量是子类,访问到的是子类的方法
2.重写基类方法
class Program { static void Main(string[] args) { //重写基类方法:在基类方法前面加上virtual,在子类方法前加上override Base b = new Base(); b.Func();//结果:我是一个父类 Sub s = new Sub(); s.Func();//结果:我是一个子类,重写 Base b1 = s; b1.Func();//结果:我是一个子类,重写 Console.ReadKey(); } } class Base { public virtual void Func() { Console.WriteLine("我是一个父类"); } } class Sub : Base { public override void Func()//此处可以直接写成 public void Func()省略掉new,我们姑且称为隐式隐藏 { Console.WriteLine("我是一个子类"); } }
从重写基类方法的例子,我们得知,对象决定我们访问到的方法,基类对象访问到基类方法,子类对象访问到子类方法.(因隐藏基类方法后,我们的父类引用访问不到子类对象,为了能访问到子类对象,所以就有了重写)
3.实现多态的例子:
(1)重写父类方法实现多太
class Standard { public virtual void Usb() { Console.WriteLine("一系列标准条文"); }
class Light : Standard { public override void Usb() { Console.WriteLine("我是个usb点灯,我亮了哈哈"); } }
class Phone:Standard { public override void Usb() { Console.WriteLine("我是手机,我在充电"); } }
class Upan : Standard { public override void Usb() { Console.WriteLine("我是upan,我存储东西"); } }
class Wind:Standard { public override void Usb() { Console.WriteLine("我是个usb电风扇,我可以吹风哈哈"); } }
class Program { static void Main(string[] args) { while (true) { Console.Write("请问你要在usb接口上插上什么设备呢\n"); Console.WriteLine("请输入你要的设备的序号 1.点灯2.手机3.u盘4.usb风扇"); string choice = Console.ReadLine(); Standard s; switch (choice) { case "1": s = new Light(); break; case "2": s = new Phone(); break; case "3": s = new Upan(); break; case "4": s = new Wind(); break; default: s = new Standard(); break; } if (s!=null) { s.Usb();//多态的实现,一种形式,实现多种功能,根据对象的不同,调用不同子类的方法 } else { Console.WriteLine("输入有误"); } Console.ReadKey(true); Console.Clear(); } } }
里氏转换中的例子改用多态实现的代码:
public class Person//基类,或称为父类 { private string name; public string Name { get { return name; } set { name = value; } } private int age; public int Age { get { return age; } set { age = value; } } private char gender; public char Gender { get { return gender; } set { gender = value; } } public Person(string name, int age, char gender) { this.Name = name; this.Age = age; this.Gender = gender; } public virtual void SayHello() { Console.WriteLine("我是{0},我今年{1}岁了,我是{2}生", name, age, gender); } } public class Teacher:Person//继承类,或称子类 { public string course; public string Cource { set{course=value;} get{return course;} } private int yearsOfService; public int YearsOfService { set { yearsOfService = value; } get { return yearsOfService; } } public override void SayHello() { Console.WriteLine("你们好,我是{0},我今年{1}岁了,教书{2}年了,我是{3}老师", Name, Age, yearsOfService, course); } public Teacher(string name,int age,char gender,string course,int yearsOfService):base( name, age, gender) //此处若没写base(name,age,gender)构造方法,便是默认调用Person的无参构造方法即base() { this.course = course; this.yearsOfService = yearsOfService; } } public class Student : Person//继承类Student { private int classId; public int ClassId { set { classId = value; } get { return classId; } } private string hobby; public string Hobby { set { hobby = value; } get { return hobby; } } public override void SayHello() { Console.WriteLine("大家好,我是{0},我今年{1}岁了,我是{2}生,我是{3}班的,我喜欢{4}", Name, Age, Gender, classId, hobby);//包含基类的成员,加自己的成员,除了基类的私有成员外,其余成员都能访问到 } public Student(string name,int age,char gender,int classId,string hobby):base(name,age,gender) { this.classId = classId; this.hobby = hobby; } }
class Program { static void Main(string[] args) { Person[] ps = new Person[]{ new Teacher("翟群",23,'女',"c#",0), new Student("何雄军",24,'男',2,"计算机"), new Person("呵呵",23,'女')}; for (int i = 0; i < ps.Length;i++ ) { ps[i].SayHello(); } Console.ReadKey(); } }
(2)抽象类抽象方法实现多太
■抽象类和抽象方法由abstract修饰
■abstract类的使用须注意:
♢抽象方法没有抽象体
♢抽象成员只能存在于抽象类中
♢抽象类可以有非抽象成员
♢抽象类派生的非抽象类必须实现抽象方法
♢抽象类只能用于基类,无法实例化
abstract class Standard { //public virtual void Usb() //{ // Console.WriteLine("一系列标准条文"); //}虚方法是要有实现体的方法,如果不需要其实现,,或不知道怎么实现的时候,那么可以使用抽象方法 public abstract void Usb(); //抽象方法不允许有实现体,相当于定义的标准,用来让子类实现 //抽象方法必须在抽象类中 } class Light : Standard { public override void Usb() { Console.WriteLine("我是个usb点灯,我亮了哈哈"); } } class Phone:Standard { public override void Usb() { Console.WriteLine("我是手机,我在充电"); } } class Upan : Standard { public override void Usb() { Console.WriteLine("我是upan,我存储东西"); } } class Wind:Standard { public override void Usb() { Console.WriteLine("我是个usb电风扇,我可以吹风哈哈"); } } class Program { static void Main(string[] args) { while (true) { Console.Write("请问你要在usb接口上插上什么设备呢\n"); Console.WriteLine("请输入你要的设备的序号 1.点灯2.手机3.u盘4.usb风扇"); string choice = Console.ReadLine(); Standard s; switch (choice) { case "1": s = new Light(); break; case "2": s = new Phone(); break; case "3": s = new Upan(); break; case "4": s = new Wind(); break; default: s = null; break; } if (s != null) { s.Usb();//多态的实现,一种形式,实现多种功能,根据对象的不同,调用不同子类的方法 } else { Console.WriteLine("输入有误"); } Console.ReadKey(true); Console.Clear(); } } }
(3)接口实现多态
■抽象的一种抽象的约定(接口是一组函数成员而不实现成员的引用类型)
■接口就是用来实现的
■语法
♢[访问修饰符]interface接口名
{
//接口成员定义,成员没有实现,实现被一个分号代替
}
♢接口只有方法,属性,事件,索引的声明
♢接口是用来实现的,所有的成员默认为public
interface IWalkable//定义一个走路的能力接口 { void Walk();//返回类型 方法名(参数列表) } interface ISound//定义一个发出声音的接口 { void Sound(); } class Car:IWalkable { public void Walk() { Console.WriteLine("我是小汽车,我会跑的快"); } } class radio:ISound { public void Sound() { Console.WriteLine("我是小喇叭,我可以广播呵 啦啦啦"); } } abstract class Animal : IWalkable, ISound { public abstract void Walk(); public abstract void Sound(); } class Cat:Animal { public override void Walk() { Console.WriteLine("我是猫猫,我会走猫步"); } public override void Sound() { Console.WriteLine("我是猫猫,我会喵喵"); } } class Person:Animal { public override void Walk() { Console.WriteLine("我是人类,我会走路哟"); } public override void Sound() { Console.WriteLine("我是人类,我可以发声哟"); } } class Program { static void Main(string[] args) { IWalkable[] walkObjects ={ new Person(), new Cat(), new Car(), }; for (int i = 0; i < walkObjects.Length;i++ ) { walkObjects[i].Walk(); } ISound[] soundObjects ={ new Person(), new Cat(), new radio() }; Console.WriteLine("\n=============\n"); for (int i = 0; i < soundObjects.Length;i++ ) { soundObjects[i].Sound(); } Console.ReadKey(true); } }
我们可以再为Person类派生一个子类Student,Student类继续重写Walk()和Sound()
class Student : Person { public override void Sound() { Console.WriteLine("我是一个重写Person父类sound()方法的子类方法"); } public override void Walk() { base.Walk();//这样既可以调用Person的Walk()方法,又有自己的重写方法 Console.WriteLine("我是重写Person父类的walk方法的子类方法"); } }