面向对象的多态 (很重要)

概念:让一个对象能够表现出多种的状态(类型)

在这之前:每个父类都要强转成子类,才可以调用每个子类的方法

            //概念:能让一个对象表现出多种的状态(类型)
            //实现多态的3中手段:1、虚方法  2、抽象类  3、接口
            
            Chinese cn1 = new Chinese("韩梅梅");
            Chinese cn2 = new Chinese("李雷");
            Japenese ja1 = new Japenese("井田子");
            Japenese ja2 = new Japenese("松下子");
            Korea ko1 = new Korea("金德善");
            Korea ko2 = new Korea("金正焕");
            American a1 = new American("奥尼尔");
            American a2 = new American("科比");
            Person[] pers = { cn1, cn2, ja1, ja2, ko1, ko2, a1, a2 };

            for (int i = 0; i < pers.Length ; i++)
            {
                if(pers[i] is Chinese )
                {
                    ((Chinese)pers[i] ).SayHello();
                }
                else if (pers[i] is Japenese )
                {
                    ((Japenese)pers[i]).SayHello();
                }
                else if(pers[i] is Korea )
                {
                    ((Korea)pers[i]).SayHello();
                }
                else
                {
                    ((American)pers[i]).SayHello();
                }
            }
            Console.ReadKey();





        }

    }
View Code

 

 

 

实现多态的手段:

1、虚方法:

步骤:

1)将父类的方法标记为虚方法,使用关键字 virtual,这个函数可以被子类重新写一遍

在子类的方法中使用override,这个方法被重写了一遍。具体调用哪一个子类的方法,取决于装的是谁的对象

 

 

 

 就不需要一大堆的强转,只需要写一句就行。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 面向对象的多态
{
    class Program
    {
        static void Main(string[] args)
        {
            //概念:能让一个对象表现出多种的状态(类型)
            //实现多态的3中手段:1、虚方法  2、抽象类  3、接口
            
            Chinese cn1 = new Chinese("韩梅梅");
            Chinese cn2 = new Chinese("李雷");
            Japenese ja1 = new Japenese("井田子");
            Japenese ja2 = new Japenese("松下子");
            Korea ko1 = new Korea("金德善");
            Korea ko2 = new Korea("金正焕");
            American a1 = new American("奥尼尔");
            American a2 = new American("科比");
            Person[] pers = { cn1, cn2, ja1, ja2, ko1, ko2, a1, a2,new English ("green"),new English ("maria") };

            for (int i = 0; i < pers.Length ; i++)
            {
                //if(pers[i] is Chinese )
                //{
                //    ((Chinese)pers[i] ).SayHello();
                //}
                //else if (pers[i] is Japenese )
                //{
                //    ((Japenese)pers[i]).SayHello();
                //}
                //else if(pers[i] is Korea )
                //{
                //    ((Korea)pers[i]).SayHello();
                //}
                //else
                //{
                //    ((American)pers[i]).SayHello();
                //}
                pers[i].SayHello();


            }
            Console.ReadKey();





        }

    }
    public class Person
    {
        private string _name;//字段
        public string Name//属性
        {
            get { return _name; }
            set{ _name = value; }
        }

        public Person(string name)//构造函数
        {
            this.Name = name;
        }
        public virtual  void SayHello()//方法,加个virtual,让他变成虚方法
        {
            Console.WriteLine("我是人类");
        }
    }
    public class Chinese:Person
    {
        public Chinese (string name)
            :base(name)
        {

        }
        public override  void SayHello()
        {
            Console.WriteLine("我是中国人");
        }
    }
    public class Japenese:Person
    {
        public Japenese (string name)
            :base(name)
        {

        }
        public override  void SayHello()
        {
            Console.WriteLine("我是小日本,我叫{0}",this.Name );
        }
    }
    public class Korea : Person
    {
        public Korea (string name)
            : base(name)
        {

        }
        public override void  SayHello()
        {
            Console.WriteLine("我是棒子国人,我叫{0}", this.Name);
        }
    }
    public class American : Person
    {
        public American (string name)
            : base(name)
        {

        }
        public override void SayHello()
        {
            Console.WriteLine("我是米国人,我叫{0}", this.Name);
        }
    }
    public class English:Person
    {
        public English (string name)
            :base(name)
        {

        }
        public override void SayHello()
        {
            Console .WriteLine ("我是英国人");
        }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 练习
{
    class Program
    {
        static void Main(string[] args)
        {
            //真的鸭子嘎嘎叫 木头鸭子吱吱叫 橡皮鸭子叽叽叫
            RealDuck rd = new RealDuck();
            MuDuck md = new MuDuck();
            XiDuck xd = new XiDuck();
            RealDuck[] ducksBark = { rd, md, xd };
            for (int i = 0; i < ducksBark .Length ; i++)
            {
                ducksBark[i].Bark();
            }
            Console.ReadKey();



        }

    }
    public class RealDuck
    {
        public virtual  void Bark()
        {
            Console.WriteLine("真的鸭子嘎嘎叫");
        }
    }
    public class MuDuck:RealDuck 
    {
        public override  void Bark()
        {
            Console.WriteLine("木头鸭子吱吱叫");
        }
    }
    public class XiDuck:RealDuck 
    {
        public override  void Bark()
        {
            Console.WriteLine("橡皮鸭子叽叽叫");
        }
    }
}

再加一个练习:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 再做一个练习
{
    class Program
    {
        //员工九点打卡,经理10点打卡,程序员不打卡
        static void Main(string[] args)
        {
            Employee em = new Employee();
            Manager ma = new Manager();
            Programer pro = new Programer();
            Employee[] ems = { ma, pro, em };
            for (int i = 0; i <ems.Length ; i++)
            {
                ems[i].DaKa();
            }
            Console.ReadKey();
        }
    }

    public class Employee//员工的意思
    {
        public virtual  void DaKa()
        {
            Console.WriteLine("九点打卡");
        }
    }

    public class Manager:Employee 
    {
        public override void DaKa()
        {
            Console.WriteLine("我是10点打卡");
        }
    }
    public class Programer:Employee
    {
        public override void DaKa()
        {
            Console.WriteLine("我不打卡");
        }
    }
}

 

 

 

2)抽象类

当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 抽象类
{
    class Program
    {
        static void Main(string[] args)
        {
            //狗狗会叫,猫咪也会叫
            //Animal an = new Animal();//抽象类不允许创建对象,因为里面什么也没有,创建也没意义
            Animal  dog = new Dog();
            Animal  cat = new Cat();
            Animal[] an = { dog, cat };
            for (int i = 0; i < an.Length ; i++)
            {
                an[i].Bark();
            }
            Console.ReadKey();

        }
    }
    public abstract class Animal   //标记一个类为抽象类 用abstract来标记
    {
        public abstract void Bark();//抽象方法是不允许有方法体的,因为我们不知道如何去实现这个方法,抽象的
    }
    public class Dog:Animal
    {
        public override void Bark()
        {
            Console.WriteLine("狗狗汪汪叫");
        }
    }
    public class Cat:Animal
    {
        public override void Bark()
        {
            Console.WriteLine("猫猫喵喵叫");
        }
    }

}

抽象类的特点:

1、抽象成员必须标记为abstract,并且不能有任何实现

2、抽象成员必须在抽象类中

3、抽象成员不能被实例化

4、子类继承抽象类后,必须把父类中的所有对象成员都重写

5、抽象成员的访问修饰符不能是private 

6、在抽象类中可以包含实例成员。并且抽象类的实例成员可以不被子类实现

7、抽象类是有构造函数的,虽然不能被实例化

8、如果父类的抽象方法中有参数,那么,继承这个抽象父类的子类在重写父类的方法时必须传入对应的参数

如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候,也必须要传入返回值

=================================================================================

如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法来实现

如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定义为抽象类-

 

posted @ 2021-07-18 17:06  静态类  阅读(105)  评论(0编辑  收藏  举报