黑马程序员--多态

来源:互联网 发布:linux fclose函数 编辑:程序博客网 时间:2024/03/28 22:36

--------------------- 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方法的子类方法");        }    }
0 0
原创粉丝点击