C#,多态的使用 - Angel's Blog.

ing
 
 
软件开发,程序设计,前端设计
 
 
首页 > code > C#,多态的使用

C#,多态的使用

 

1)多态:

多态就是针对不同类别的对象,在使用相同的方法有不同的行为方式。

先看一个demo:

demo:

 

------------------------Person start-----------------
   //修改类Person,用 abstract修饰,这里的字段等省略。
    public abstract class Person
    {
        public Person() { }
        public Person(int age , Genders gender , string name)
        {
            //代码省略..
        }
        protected int _Age;
        protected Genders _Gender;
        protected string _Name;

        public string Name
        {
            //代码省略..
        }

        public Genders Gender
        {
            //代码省略..
        }

        public int Age
        {
            //代码省略..
        }
        public enum Genders
        {
            Male , Female
        }

        public abstract string Greet();//是一个未实现的抽象方法,即将等待实现。

    }
------------------------Person end-----------------

 

-----------------------Student start-------------------
    public class Student:Person//继承Person
    {
        //字段(额外加了两个字段)
        private string _Hobby;

        public string Hobby
        {
            //代码省略..
        }
        //构造函数
        public Student() { }//默认
        public Student(int age, Genders gender, string name, string hobby)
            : base(age, gender, name)
        {
            //Student类自定义的属性
            this.Hobby = hobby;
        }

        //方法
        //在Student类中使用重写的虚方法
        public override string Greet()
        {
            string message = string.Format("此学生的年龄{0},性别{1},名字{2},爱好{3}。",
                this.Age, this.Gender, this.Name, this.Hobby);
            return message;
        }
-----------------------Student end-------------------

同理,Teacher中的抽象方法也需要实现。

 

-----------------------Teacher start-------------------
    public class Teacher:Person//子类Teacher继承父类Person
    {
        public Teacher() { }
        public Teacher(int age, Genders gender, string name, int workYear, int earnMoney)
        {
            //代码省略..
        }
        private int _EarnMoney;
        private int _WorkYear;

        public int WorkYear
        {
            //代码省略..
        }

        public int EarnMoney
        {
            //代码省略..
        }
        //在Teacher类中将父类中的抽象方法实现
        public override string Greet()
        {
            string message = string.Format("姓名{0},性别{1},年龄{2},工作年限{3},月薪{4}",
                this.Name, this.Gender, this.Age, this.WorkYear, this.EarnMoney);
            return message;
        }
    }
-----------------------Teacher end-------------------

2)关于抽象类和抽象方法:

在demo 中,定义的一个抽象类Person,且使用了一个Person中没有实现的方法 – 抽象方法Greet()

,然后Student和Teacher类调用这个抽象方法,在各自的类中实现他们调用的同一个方法,多态就

实现了。

抽象方法是一个没有实现的方法,用abstract关键字修饰;

所以,含有抽象方法的类,必然是抽象类;但是抽象类中不一定都是抽象方法。

抽象方法的语法:

 

访问修饰符 abstract 返回类型 方法名();

抽象类的语法:

 

访问修饰符 abstract class 类名{}

注意:

①:抽象类不能被实例化:

譬如将demo中的抽象类Person 实例化后,会报错:

所以,想实现该抽象类的抽象方法,必须通过他的子类实现。

②:抽象类不能用sealed(密封)或者static(静态)修饰。

这个更好理解了,既然抽象类中的抽象方法是要子类实现的,如果用sealed或者static修饰,

子类无法访问,那你说这个抽象方法存在有什么意义呢?(浪费空气)

3)抽象类、抽象方法的使用:

在子类中实现方法的重写:

当抽象类派生一个子类,这个子类会继承父类的所有特性特征,其中含有没有实现的抽象方法,

且抽象方法的实现必然在其派生类(子类)里实现(之前的demo已经指明),子类是抽象类的except。。

在子类实现抽象类方法的语法:

 

访问修饰符 override 返回类型 方法名(){//方法体}

4)里氏替换:

:is 操作符的使用:

is操作符,用来检查是否和给定的类型相同,譬如判断object类型是否为string 类型:

使用is操作符,在进行判断的时候,如果提供的对象可以允许强制转换为现提供的类型,

整个is表达式的结果为true。

 

        if (object is string){}

 

 

:as 操作符的使用:

as操作符用来两个对象之间的转换,在这里,不需要获取元素强制转换,而只需要 as操作符:

demo1:

 

        private void button2_Click(object sender, EventArgs e)
        {
            ArrayList students = new ArrayList();
            Student shanShan = new Student(18, Person.Genders.Female, "shanShan", "history");
            Student wrong = new Student(25, Person.Genders.Male, "wrong", "bay");
            students.Add(shanShan);
            students.Add(wrong);
            //使用as操作符进行类型转换
            for (int i = 0; i < students.Count; i++)
            {
                Student stu = students[i] as Student;
                MessageBox.Show(stu.Hobby);
            }
        }

5)虚方法的使用:

虚方法的使用,无非是想给一个默认方法。

①:使用虚方法实现多态:

实现思路:在父类定义虚方法,在子类override(重写)虚方法(虚方法可以被重写,可以有具体的实现):

虚方法语法:

 

访问修饰符 virtual 返回类型 方法名(){//方法体}

demo2:

 

--------------------修改Person类--------------------------
//之前的代码省略..
        //public abstract string Greet();
        public virtual string Greet()//虚方法在Person类中默认
        {
            string sex;
            switch (this.Gender)
            {
                case Genders.Male:
                    sex = "男人";
                    break;
                case Genders.Female:
                    sex = "女人";
                    break;
                default:
                    sex = "unknow sex";
                    break;
            }
            string msg = string.Format("年龄{0},性别{1},名字{2}", this.Age, sex, this.Name);
            return msg;
        }

 

---------------------修改Student类--------------------------
//之前代码省略..
        //在Student类中使用重写的虚方法
        public override string Greet()
        {
            string message = string.Format("此学生的年龄{0},性别{1},名字{2},爱好{3}。",
                this.Age, this.Gender, this.Name, this.Hobby);
            return message;
        }

在这里,Teacher会使用默认的虚方法而不重写:

 

---------------------修改Teacher类--------------------------
        //在Teacher类中使用了默认的虚方法(没有重写)
        public override string Greet()
        {
            return base.Greet();
        }

将重写的content show出来:

 

        //在Student类的虚方法使用了重写
        private void button3_Click(object sender, EventArgs e)
        {
            Student stu = new Student(20, Person.Genders.Female, "hanmeimei", "sing");
            MessageBox.Show(stu.Greet());

        }
        //在Teacher类中使用默认的虚方法(没有重写)
        private void button4_Click(object sender, EventArgs e)
        {
            Teacher tea = new Teacher(40, Person.Genders.Male, "heihei", 10, 5000);
            MessageBox.Show(tea.Greet());
        }

:Equals()方法的重写:

语法:

 

        public virtual equals(Object obj)

demo3:

在btn5中创建一个集合对象students,添加元素,然后打印添加到集合的元素数量:

 

        private void button5_Click(object sender, EventArgs e)
        {
            ArrayList students = new ArrayList();
            Student liang = new Student(18 , Person.Genders.Male , "liang" , "heid");
            Student zhi = new Student(19, Person.Genders.Female, "zhi", "laugh");
            students.Add(liang);
            students.Add(zhi);
            Student stu = new Student(18, Person.Genders.Male, "liang", "heid");
            //下面来打印一次移除stu对象前的集合个数:
            MessageBox.Show(string.Format("总计{0}个人", students.Count.ToString()));
            students.Remove(stu);
            //再打印移除对象后的集合个数:
            MessageBox.Show(string.Format("总计{0}个人", students.Count.ToString()));
        }

运行之后,发现在删除“stu”对象前后集合元素的数量没有变化,依旧是 2 ;

这也就是无法通过和 “stu” 对象相同的值来获取另一个和stu相同的对象 “liang” 。

在这里,Object都有一个Equals()方法,用来确认两个对象是否相等。

demo4:

在Student类中添加一个Equals()的重写方法:

 

//之前的代码省略..
        //
        //public override string Greet()
        //{
        //    string message = string.Format("此学生的年龄{0},性别{1},名字{2},爱好{3}。",
        //        this.Age, this.Gender, this.Name, this.Hobby);
        //    return message;
        //}
        //Equals方法重写
        public override bool Equals(object obj)
        {
            //return base.Equals(obj);
            Student tr = obj as Student;
            if (tr == null)
            {
                return false;
            }
            if (tr._Name == this._Name && tr._Gender ==this._Gender && tr._Hobby == this._Hobby && tr._Age ==this._Age)
            {
                return true;
            }
            return false;
        }

这时在去打印,则相等的对象的值会被删除。

 

或者通过RSS 关注本站的更新 ^ O ^ 。” —  by  转载请注明:来自 Angel's Blog.
本文永久链接: http://www.0ee.com/2010/11/28/c-sharp-abstract-and-override-virtual.html
 
分类: code标签: , ,
 
  • QQ书签
  • Del.icio.us
  • 百度收藏
  • Google
  • 饭否
  • FriendFeed
 

 
评论 (18) Trackbacks (0)
发表评论 Trackback
 
18 Comments Contributed by Visitors
  1.     uninux 2010年12月1日11:08 11#

    换皮肤了啊。。。

  2.     Angel 2010年12月1日12:59 12#

    uninux :

    换皮肤了啊。。。

    恩,,换好几天了,,呵呵。 ok

  3.     云在天边 2010年12月2日08:26 13#

    试试,可以了

  4.     Angel 2010年12月2日11:14 14#

    @云在天边
    okay,已经看到你的ip了,255.171.*.*,3Q。

  5.     云在天边 2010年12月2日11:43 15#

    @Angel

    GAE这几天出故障了吧,IPv6的remote_ipaddr获取的是错误的,呵呵 ok

  6.     Xiao Ta 2010年12月2日13:51 16#

    我是来请教js嵌套回复的…. ok

  7.     Angel 2010年12月3日12:21 17#

    @云在天边
    额,才知道self.request.remote_addr用这个获取的。。不是很清楚。。

  8.     Angel 2010年12月3日12:41 18#

    @Xiao Ta
    传诵门,可以参照houkai的文章。

Leave Comments Here...

:) :-D :( :-o 8-O :-? 8) lol :-x :-P oops cry evil twisted wink ? idea :-| arrow mrgreen roll !

(required)

(required)

网址随您("http://"可以省略)

(Ctrl+Enter)

  • 本站不会泄露您的 Email 地址, 敬请放心.
  • 本站已开启缓存, 请不要重复提交评论.
  • 请注意: 带有 《广告(链)、不健康、或者 产品名字》 的评论一律视为spam.
  • 支持常用 HTML 标签调用, 插入 HTML 标签需注意: < == &lt;> == &gt;.
  • 仅当某人针对您的评论做出回应时, 您才会收到由本站发出的邮件通知.
  • 如您希望以相同方式通知某位网友, 请点击  按钮进行回复.
  • 允许在评论中使用如下代码: 
    <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> 
    <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> 
    .
  • 鼠标悬浮到评论中的 @someone 区域即可自动显示 someone 的评论内容.
 
 
  • 正在加载...