黑马程序员技术交流社区

标题: 一个关于类的问题 [打印本页]

作者: 宋超    时间: 2012-3-22 22:58
标题: 一个关于类的问题
类的重载和重写有什么不一样的地方?最好举个例子?谢谢
作者: 蔚强    时间: 2012-3-23 00:50
重载是在类里面,如类的构造函数的重载啊,而重写是发生在父类与子类之间的,子类重写父类的方法。
作者: →篱誸de~箭    时间: 2012-3-23 01:03
重载、重写和隐藏的定义:

重载:同一个作用域内发生(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同。这样才能通过传递不同的参数来决定到底调用哪一个。而返回值类型不同是不能构成重载的。

重写:继承时发生,在子类中重新定义父类中的方法,子类中的方法和父类的方法是一样的

  例如:基类方法声明为virtual(虚方法),派生类中使用override申明此方法的重写.

隐藏:基类方法不做申明(默认为非虚方法),在派生类中使用new声明此方法的隐藏。

重载时,根据参数选择调用的方法;

重写时,访问父类子类皆调用子类的重写方法;

隐藏时,访问父类则调用父类的方法,子类子类的方法。


补充:重写override一般用于接口实现和继承类的方法改写,要注意

  1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;

  2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;

  3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;

  4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

这三个概念都是与OO中的多态有关系的。如果单是区别重载与覆盖这两个概念是比较容易的,但是隐藏这一概念却使问题变得有点复杂了,下面说说它们的区别吧。

  重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。

  覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。

  隐藏是指派生类中的函数把基类中相同名字的函数屏蔽掉了。隐藏与另外两个概念表面上看来很像,很难区分,其实他们的关键区别就是在多态的实现上。什么叫多态?简单地说就是一个接口,多种实现吧。1,重写,必然发生在基类和派生类中,其类函数用virtual修饰,派生类用override修饰
2,隐藏,在子类中写一个和基类一样名字(参数不同也算)的非虚函数,会让基类中的函数被隐藏,这时候一般编 译时会报一个警,子类中的函数用new修饰一下就不报警了
3,重载,必然发生在一个类中,函数名相同,参数类型或者顺序不同构成重载,与返回类型无关
------------


参考
http://topic.csdn.net/u/20110105/14/77e68d33-7ff2-4916-8a69-bba27d64af44.html


下面是自己写的两个例子,挺有代表性的,一看就知道是什么了。。。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace C_sharp_control
{
    public class person
    {
        protected readonly int id;
        protected string name;
        public person(int id, string name)
        {
            this.id=id;
            this.name=name;
        }
        public int ID
        {
            get
            {
                return this.id;
            }
        }
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                this.name=value ;
            }
        }
        public void show()
        {
            Console.WriteLine("I'm a person");
        }
    }
    public class student : person
    {
        protected int math;
        protected int chinese;
        protected int total;
        public student(int id, string name, int math, int chinese):base(id,name)
        {
           this.math=math;
            this.chinese=chinese;
            this.total=this.math+this.chinese;
        }
        public int Math
        {
            get
            {
                return this.math;
            }
            set
            {
                this.math=value;
            }
        }
        public int Chinese
        {
            get
            {
                return this.chinese;
            }
            set
            {
                this.chinese=value;
            }
        }
        public  void show()
        {
         
            Console.WriteLine("I'm a student");
        }
    }
    public class goodstudet : student
    {
        private int scholarship;
        public goodstudet(int id, string name, int math, int chinese, int scholarship)
            : base(id, name, math, chinese)
        {
            this.scholarship = scholarship;
        }
        public int Scholarship
        {
            get
            {
                return this.scholarship;
            }
            set
            {
                this.scholarship=value ;
            }
        }
        public  void show()
        {
            Console.WriteLine("I'm a good student");
        }
     
    }
    class Program
    {
        static void show(person per)
        {
             per.show();
        }
        static void Main(string[] args)
        {
            person []array={new person(1,"boy"),new student(1,"NOY",44,55),new goodstudet(1,"Girl",23,54,56654)};
            for (int i = 0; i < 3; i++)

            {
              array.show();
            }
        }  
    }
}




上面是的隐藏的代码,下面是重写的代码 。。。。

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

namespace C_sharp_control
{
    public class person
    {
        protected readonly int id;
        protected string name;
        public person(int id, string name)
        {
            this.id=id;
            this.name=name;
        }
        public int ID
        {
            get
            {
                return this.id;
            }
        }
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                this.name=value ;
            }
        }
        public virtual void show()
        {
            Console.WriteLine("I'm a person");
        }
    }
    public class student : person
    {
        protected int math;
        protected int chinese;
        protected int total;
        public student(int id, string name, int math, int chinese):base(id,name)
        {
           this.math=math;
            this.chinese=chinese;
            this.total=this.math+this.chinese;
        }
        public int Math
        {
            get
            {
                return this.math;
            }
            set
            {
                this.math=value;
            }
        }
        public int Chinese
        {
            get
            {
                return this.chinese;
            }
            set
            {
                this.chinese=value;
            }
        }
        public override void show()
        {
         
            Console.WriteLine("I'm a student");
        }
    }
    public class goodstudet : student
    {
        private int scholarship;
        public goodstudet(int id, string name, int math, int chinese, int scholarship)
            : base(id, name, math, chinese)
        {
            this.scholarship = scholarship;
        }
        public int Scholarship
        {
            get
            {
                return this.scholarship;
            }
            set
            {
                this.scholarship=value ;
            }
        }
        public override void show()
        {
            Console.WriteLine("I'm a good student");
        }
     
    }
    class Program
    {
        static void show(person per)
        {
             per.show();
        }
        static void Main(string[] args)
        {
            person []array={new person(1,"boy"),new student(1,"NOY",44,55),new goodstudet(1,"Girl",23,54,56654)};
            for (int i = 0; i < 3; i++)
            {
              array.show();
            }
        }  
    }
}






作者: 蔚强    时间: 2012-3-23 01:19
public class People
    {
        private string name;
        private int age;
        public People() { }//这是没有参数的构造函数
        public People(string name, int age)//这是有俩个参数的构造函数
        {
            this.name = name;
            this.age = age;
        }
        public virtual void Print()
        {
            Console.WriteLine("这是开山老祖创的秘籍!");
        }
    }
    public class ChinesePerson : People
    {
        public override void Print()
        {
            Console.WriteLine("这是中国人自己创的武林秘籍");
        }

    }
    public class My : People
    {
        public override void Print()
        {
            Console.WriteLine("这是我自己自创的武功秘籍!");
        }
    }

People p = new People();
p.Print();这是第一种检验覆盖父类方法的
ChinesePerson Chinesse = new ChinesePerson();
Chinesse.Print();
My my = new My();
my.Print();
第二种的话是利用类的多态性,因为下面俩个子类是继承People父类的
People []p = new People [2];
for(int i=0;i<2;i++)
{
       p[i] = new People();
        //   p[i].Print();
}
     p[0] = new ChinesePerson();
     p[0].Print();
     p[1] = new My();
     p[1].Print();
其实我也是C#新手,感觉还是自己写但马会理解的更加清晰一点的,我建议你以后有什么地方不明白,自己写代码验证这到底是怎么回事。这样你自己真的会有所收益的!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2