码迷,mamicode.com
首页 > 其他好文 > 详细

第七章 继承和多态

时间:2014-11-29 00:03:15      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   使用   sp   

1 继承

1.1 基类与派生类

C#中的类不支持多继承。只有在类和接口之间可以实现多继承。

        public static void Main()
        {
            Business c1 = new Business();
            c1.Name = "李明";
            c1["办公电话"] = "07188888888";
            c1.Output();
            ClassMate c2 = new ClassMate();
            c2.Name = "张鹏";
            c2.Birthday = new DateTime(1978, 12, 31);
            c2.Output();
        }
    /// <summary>
    /// 基类:联系人Contact
    /// </summary>
    public class Contact
    {
        //字段
        protected string m_name;
        protected string m_homePhone = "未知";
        protected string m_busiPhone = "未知";
        protected string m_mobilePhone = "未知";
        //属性
        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                m_name = value;
            }
        }
        //索引函数
        public string this[string sType]
        {
            get
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "住宅电话":
                        return m_homePhone;
                    case "办公电话":
                        return m_busiPhone;
                    case "手机":
                        return m_mobilePhone;
                    default:
                        return null;
                }
            }
            set
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "住宅电话":
                        m_homePhone = value;
                        break;
                    case "办公电话":
                        m_busiPhone = value;
                        break;
                    case "手机":
                        m_mobilePhone = value;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }

        //构造函数
        public Contact()
        {
        }

        //方法
        public void Output()
        {
            Console.WriteLine("姓名:{0}", m_name);
            Console.WriteLine("住宅电话:{0}", m_homePhone);
            Console.WriteLine("办公电话:{0}", m_busiPhone);
            Console.WriteLine("手机:{0}", m_mobilePhone);
            Console.WriteLine();
        }
    }
    /// <summary>
    /// 派生类:商务Business
    /// </summary>
    public class Business:Contact
    {
        //字段
        protected string m_busiFax = "未知";
        protected string m_title = "先生/女士";

        //属性
        public string Title
        {
            get
            {
                return m_title;
            }
            set
            {
                m_title = value;
            }
        }
    }
    /// <summary>
    /// 派生类:同学ClassMate
    /// </summary>
    public class ClassMate:Contact
    {
        //字段
        protected DateTime m_birthday;

        //属性
        public DateTime Birthday
        {
            get
            {
                return m_birthday;
            }
            set
            {
                m_birthday = value;
            }
        }
    }

1.2 隐藏基类的成员

通过new关键字来隐藏基类中的成员,来存储不同的信息或执行不同的操作。

new关键字放在访问限制修饰符的前后均可,但一定要在成员的类型说明之间

隐藏基类成员时所使用的new关键字属于一种修饰符,与创建对象的new操作符是完全不同的。

1.3 base关键字

this关键字可以用来访问当前对象,而base关键字则可以用来访问基类对象,调用基类对象的成员。

//方法
public new void Output()
{
    base.Output();
    Console.WriteLine("...");
}

1.4 继承中的构造函数和析构函数

创建一个派生类的实例,在执行其构造函数代码之前,会隐式的调用基类的构造函数。

析构函数的调用顺序相反,首先调用当前对象的析构函数,依次调用各级基灶的析构函数。

对于不带参数的默认构造函数,如果基类中已经有了定义,派生类可以隐式的继承。一旦基类中定义了带参数的构造函数,派生类的继承就不是隐式的了,而是要提供参数数量和类型都是基类构造函数相同的构造函数。例如基类Contact中定义了下面的构造函数:

public Contact(string sName)
{
    m_name=sName;
}

那么下面的代码是错误的:

Business c1= new Business("李四");
Classmate c2= new Classmate("张鹏");

下面是一个完整的示例:

    public class NewInheritSample
    {
        static void Main()
        {
            //Business c2 = new Business();错误的代码
            Business c1 = new Business("李明");
            c1["办公电话"] = "01088888888";
            c1["商务传真"] = "01066666666";
            c1.Output();
            ClassMate c2 = new ClassMate("张鹏");
            c2.Birthday = new DateTime(1977, 02, 19);
            c2.Output();
        }
    }
    /// <summary>
    /// 基类:联系人Contact
    /// </summary>
    public class Contact
    {
        //字段
        protected string m_name;
        protected string m_homePhone = "未知";
        protected string m_busiPhone = "未知";
        protected string m_mobilePhone = "未知";
        //属性
        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                m_name = value;
            }
        }
        //索引函数
        public string this[string sType]
        {
            get
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "住宅电话":
                        return m_homePhone;
                    case "办公电话":
                        return m_busiPhone;
                    case "手机":
                        return m_mobilePhone;
                    default:
                        return null;
                }
            }
            set
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "住宅电话":
                        m_homePhone = value;
                        break;
                    case "办公电话":
                        m_busiPhone = value;
                        break;
                    case "手机":
                        m_mobilePhone = value;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }

        //构造函数
        public Contact()
        {
        }

        public Contact(string sName)
        {
            m_name = sName;
        }

        //方法
        public void Output()
        {
            Console.WriteLine("姓名:{0}", m_name);
            Console.WriteLine("住宅电话:{0}", m_homePhone);
            Console.WriteLine("办公电话:{0}", m_busiPhone);
            Console.WriteLine("手机:{0}", m_mobilePhone);
            Console.WriteLine();
        }
    }
    /// <summary>
    /// 派生类:商务Business
    /// </summary>
    public class Business:Contact
    {
        //字段
        protected string m_busiFax = "未知";
        protected string m_title = "先生/女士";

        //属性
        public string Title
        {
            get
            {
                return m_title;
            }
            set
            {
                m_title = value;
            }
        }

        //索引函数
        public new string this[string sType]
        {
            get
            {
                string type=sType.ToUpper();
                switch(type)
                {
                    case "商务传真":
                        return m_busiFax;
                    default:
                        return base[sType];
                }
            }
            set
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "商务传真":
                        m_busiFax = value;
                        break;
                    default:
                        base[sType] = value;
                        break;
                }
            }
        }

        //构造函数
        public Business(string sName)
            : base(sName)
        {
        }

        //方法
        public new void Output()
        {
            base.Output();
            Console.WriteLine("商务传真:{0}", m_busiFax);
            Console.WriteLine();
        }
    }
    /// <summary>
    /// 派生类:同学ClassMate
    /// </summary>
    public class ClassMate:Contact
    {
        //字段
        protected DateTime m_birthday;

        //属性
        public DateTime Birthday
        {
            get
            {
                return m_birthday;
            }
            set
            {
                m_birthday = value;
            }
        }

        //构造函数
        public ClassMate(string sName)
            : base(sName)
        {
        }

        //方法
        public new void Output()
        {
            base.Output();
            Console.WriteLine("生日:{0}", m_birthday.ToString());
        }
    }

 

2 多态性

2.1 虚拟方法和重载方法

派生类很少一成不变的去继承基类中的所有成员。一种情况是:派生类中的方法成员隐藏基类中同名的方法成员,通过new关键字对成员修饰。另一种更普遍和灵活的情况是:将基类的方法成员定义为虚拟方法,而在派生类中对虚拟方法进行重载。后者的优势在于它可以实现运行时的多态性。

基类的虚拟方法通过关键字virtual进行定义。下面是一个完整的例子:

bubuko.com,布布扣
    class VirtualInheritSample
    {
        static void Main(string[] args)
        {
            Business c1 = new Business("李明");
            c1["办公电话"] = "01088888888";
            c1["商务传真"] = "01066666666";
            ClassMate c2 = new ClassMate("张鹏");
            c2.Birthday = new DateTime(1977, 02, 19);

            Contact c = c1;
            c.Output();//for Business
            c = c2;
            c.Output();//for Classmate
        }
    }
    /// <summary>
    /// 基类:联系人Contact
    /// </summary>
    public class Contact
    {
        //字段
        protected string m_name;
        protected string m_homePhone = "未知";
        protected string m_busiPhone = "未知";
        protected string m_mobilePhone = "未知";
        //属性
        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                m_name = value;
            }
        }

        //虚拟索引函数
        public virtual string this[string sType]
        {
            get
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "住宅电话":
                        return m_homePhone;
                    case "办公电话":
                        return m_busiPhone;
                    case "手机":
                        return m_mobilePhone;
                    default:
                        return null;
                }
            }
            set
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "住宅电话":
                        m_homePhone = value;
                        break;
                    case "办公电话":
                        m_busiPhone = value;
                        break;
                    case "手机":
                        m_mobilePhone = value;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }

        //构造函数
        public Contact()
        {
        }

        public Contact(string sName)
        {
            m_name = sName;
        }

        //虚拟方法
        public virtual void Output()
        {
            Console.WriteLine("姓名:{0}", m_name);
            Console.WriteLine("住宅电话:{0}", m_homePhone);
            Console.WriteLine("办公电话:{0}", m_busiPhone);
            Console.WriteLine("手机:{0}", m_mobilePhone);
            Console.WriteLine();
        }
    }
    /// <summary>
    /// 派生类:商务Business
    /// </summary>
    public class Business:Contact
    {
        //字段
        protected string m_busiFax = "未知";
        protected string m_title = "先生/女士";

        //属性
        public string Title
        {
            get
            {
                return m_title;
            }
            set
            {
                m_title = value;
            }
        }

        //重载索引函数
        public override string this[string sType]
        {
            get
            {
                string type=sType.ToUpper();
                switch(type)
                {
                    case "商务传真":
                        return m_busiFax;
                    default:
                        return base[sType];
                }
            }
            set
            {
                string type = sType.ToUpper();
                switch (type)
                {
                    case "商务传真":
                        m_busiFax = value;
                        break;
                    default:
                        base[sType] = value;
                        break;
                }
            }
        }

        //构造函数
        public Business(string sName)
            : base(sName)
        {
        }

        //重载方法
        public override void Output()
        {
            base.Output();
            Console.WriteLine("商务传真:{0}", m_busiFax);
            Console.WriteLine();
        }
    }
    /// <summary>
    /// 派生类:同学ClassMate
    /// </summary>
    public class ClassMate:Contact
    {
        //字段
        protected DateTime m_birthday;

        //属性
        public DateTime Birthday
        {
            get
            {
                return m_birthday;
            }
            set
            {
                m_birthday = value;
            }
        }

        //构造函数
        public ClassMate(string sName)
            : base(sName)
        {
        }

        //重载方法
        public override void Output()
        {
            base.Output();
            Console.WriteLine("生日:{0}", m_birthday.ToString());
        }
    }
View Code

 提示:

--如果派生类中使用override关键字定义了重载方法,那么也就允许该类自己的派生类继续重载这个方法,因此重载方法也默认是一种虚拟方法,但不能同时使用virtual和override修饰一个方法。

--虚拟方法可以在派生类中重载,因此虚拟方法不能是私有的

--在基类和派生类中,对同一个虚拟方法和重载方法的访问限制应当相同,要么都使用public,要么都使用protected。

2.2 抽象类和抽象方法

第七章 继承和多态

标签:style   blog   http   io   ar   color   os   使用   sp   

原文地址:http://www.cnblogs.com/boywg/p/4129529.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!