C#中的多态

需求如下:

1、已知一个SE类、PM类继承了Employee类;SE和PM类有一些属性,并且都有一个方法SayiHi(),我们把SE和PM共同的属性抽到Employee父类

2、使用集合存储Employee;

3、SE类中的SayiHi()方法要输出工程师的信息,PM中的SayiHi()方法要输出项目经理的信息,有相同的信息,也有各自不同的信息;

 

父类:Employee 员工类

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

namespace Lesson6.Example
{

    /// <summary>
    /// 员工类
    /// </summary>
    public class Employee
    {
        /// <summary>
        /// 工号
        /// </summary>
        public string ID { get; set; }

        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public Gender Gender { get; set; }


         
    }
}

子类:SE类 工程师类

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

namespace Lesson6.Example
{
    public class SE : Employee
    {
        public SE()
        {
        }
        public SE(string id, string name, int age, Gender gender, int Popularity)
        {
            this.Name = name;
            this.Age = age;
            this.Gender = gender;
            this.Popularity = Popularity;
        }
        /// <summary>
        /// 人气
        /// </summary>
        public int Popularity { get; set; }

        public  string SayHi()
        {
            string message = string.Format("大家好,我是{0},今年{1}岁,工号是{2},我的人气值高达{3}!",this.Name,this.Age,this.ID,this.Popularity);
            return message;
        }
    }
}

 

子类:PM 项目经理类

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

namespace Lesson6.Example
{
    /// <summary>
    /// PM类
    /// </summary>
    public class PM : Employee
    {
        public PM()
        {
        }
        public PM(string id, string name, int age, Gender gender, int yearOfExperience)
        {
            this.Name = name;
            this.Age = age;
            this.Gender = gender;
            this.YearOfExperience = yearOfExperience;
        }

        /// <summary>
        /// 资历
        /// </summary>
        public int YearOfExperience { get; set; }

        /// <summary>
        /// 问好,返回值:问好的内容
        /// </summary>
        /// <returns></returns>
        public  string SayHi()
        {
            string message;
            message = string.Format("大家好,我是{0},今年{1}岁,项目管理经验{2}年。", this.Name, this.Age, this.YearOfExperience);
            return message;
        }
    }
}

 

测试类:Program类

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

namespace Lesson6
{
    class Program
    {
        static void Main(string[] args)
        {
            // 实例化SE对象
            SE ai = new SE("112", "张三", 25, Gender.男, 100);
            // 实例化SE对象
            SE joe = new SE("113", "joe", 26, Gender.男, 100);

            // 实例化PM对象
            PM pm = new PM("113", "pm", 30, Gender.女, 100);


            // 泛型类型是父类,要使用的是子类的方法,要用is来判断具体的子类类型
            List<Employee> empls = new List<Employee>();
            empls.Add(ai);
            empls.Add(joe);
            empls.Add(pm);

            foreach (Employee empl in empls)
            {
                // 继承才能用is
                if (empl is SE)
                {
                    Console.WriteLine(((SE)empl).SayHi());
                }
                if (empl is PM)
                {
                    Console.WriteLine(((PM)empl).SayHi());
                }
                
            }
             
        }
    }
}

 

分析,我们如果存储的是Employee这个集合的话,我们需要使用is 来判断具体是哪个子类,然后再强制转换成该子类,才能调用该子类的方法。

以上是可以解决问题的。

但我们可以使用多态来更灵活,自动的处理。

 

首先,在父类Employee中建一个virtual虚方法。

 public virtual string SayHi()
        {
            string message = string.Format("大家好!");
            return message;
        }

 

然后修改SE和PM类中的SayHi()方法前面加上override 关键字,表示重写父类的方法。

/// <summary>
        /// 问好,返回值:问好的内容
        /// </summary>
        /// <returns></returns>
        public override string SayHi()
        {
            string message;
            message = string.Format("大家好,我是{0},今年{1}岁,项目管理经验{2}年。", this.Name, this.Age, this.YearOfExperience);
            return message;
        }

 

最后,我们在集合遍历时,可以不使用is来判断,因为面向对象的多态特性帮我们自动地判断了。

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

namespace Lesson5
{
    class Program
    {
        static void Main(string[] args)
        {
            // 实例化SE对象
            SE ai = new SE("112", "张三", 25, Gender.男, 100);

            SE joe = new SE("113", "joe", 26, Gender.男, 100);

            PM pm = new PM("113", "pm", 30, Gender.女, 100);

            List<Employee> empls = new List<Employee>();
            empls.Add(ai);
            empls.Add(joe);
            empls.Add(pm);

            // 遍历Employee集合
            foreach (Employee empl in empls)
            {
                // 无需判断是哪个子类,面向对象的多态特性自动帮助我们判断
                Console.WriteLine(empl.SayHi());
            }

            Employee ema = new SE("113", "ema", 30, Gender.女, 100);

            Console.WriteLine(ema.SayHi());
        }
    }
}

根据以上实现代码,我们会发现多态其实主要是用来解决继承带来的问题的,可以帮助我们更好地解决不同的子类,产生执行不同的结果。

 

posted @ 2017-04-10 01:24  xiaobudong  阅读(325)  评论(0编辑  收藏  举报