构造函数,是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。写一个类,如果没有写任何的构造函数,那么这个类有一个默认的无参数的构造函数。如果写了构造函数,那么在这个类中就有两个构造函数,一个默认的,一个是自己写的,不过,自己写了构造函数,之前默认的那个构造函数就不能用了,如果还想用之前的那个默认的构造函数,就必须再重新写一个无参数的构造函数。
构造函数的命名与类名相同,没有返回值,也不能用void修饰,只有访问修饰符public等。
class Program { static void Main(string[] args) { Pet p1 = new Pet();//此处执行构造函数Pet() Pet p2 = new Pet(100);//此处执行构造函数Pet(int) Console.WriteLine(p1.Health); Console.WriteLine(p2.Health); Console.ReadKey(); } } class Pet { private int health; private int fulllevel; //构造函数没有返回值,名字和类名相同 //构造函数在对象被new的时候调用 //如果不指定构造函数,即注释掉下面的Pet()函数,类中会默认创建一个无参的构造函数 //当制定了一个构造函数,就不会有默认的无参构造函数,若需要无参构造函数则需要自己写 public Pet() { this.health = 20; this.fulllevel = 100; } public Pet(int health) { this.health = health;//后一个health是形参的health } public int Health { get { return health; } } }
一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的;每次实例化(既上面的new A())一个类时,就会调用构造函数。
继承是根据一个类来定义另一个类,子类包含父类中所有字段,例如,哺乳动物为一个类,人为哺乳动物的一个派生类。
class Person//父类 { public string Name { get; set; } public int Age { get; set; } public Person() { Console.WriteLine("A构造"); } } class Chinese:Person//派生类,包含有Person类中的Name,Age字段和自生的gender字段 { public string gender { get; set; } public Chinese() { Console.WriteLine("B构造"); } }
子类对象可以指向父类中的变量,显式转换转换失败会报错,而as转换失败不会报错,会使结果为null。还有个类型的判断符为is,用于判断一个类型是否为指定类型,返回值为true或者false。
class Program { static void Main(string[] args) { Chinese chi=new Chinese();//一个new就是一个对象 //chi.gender="man"; //chi.Age = 15; //Console.WriteLine(chi.Age); Person people = chi;//父类变量可以指向子类的变量 chi.gender="man"; //Chinese ch = people;//无法把子类变量指向父类的变量 Chinese ch = (Chinese)people;//通过显式转换可以使子类变量指向父类的变量,如果转换失败就抛异常 Chinese ch1 = people as Chinese;//如果转换失败不报错,结果为null if (ch1 is Chinese) { Console.WriteLine(ch1.Name); } Console.ReadKey(); } }
父类和子类中,你声明的是哪一个,调用时就调用哪一个,如下面的例子
static void Main(string[] args) { //子类和父类的调用时,前面声明的是子类就调用子类,声明的是父类就调用父类 //因为声明了哪一个,类型指针就是哪一个 Human xiaoming=new Human(); xiaoming.Age=20; xiaoming.Gender=true; xiaoming.Name="小明"; xiaoming.SayHi(); Console.WriteLine(); Person xiaohong=new Human(); xiaohong.Age = 25; xiaohong.Gender = false; xiaohong.Name = "小红"; xiaohong.SayHi(); Console.ReadKey(); } } class Person { #region 姓名 /// <summary> /// 姓名 /// </summary> private string name; public string Name { get { return name; } set { name = value; } } #endregion #region 年龄 /// <summary> /// 年龄 /// </summary> private int age; public int Age { get { return age; } set { age = value; } } #endregion #region 性别 /// <summary> /// 性别 /// </summary> private bool gender; public bool Gender { get { return gender; } set { gender = value; } } #endregion public virtual void SayHi()//虚方法,用于重写 { Console.WriteLine("父类"); } } class Human:Person { public void SayHi() { Console.WriteLine("子类"); } } }
最后执行代码的结果为
这是因为你声明了哪个类型,类型指针就确定了是哪一个,声明了Person父类,就算实例化new为子类Human,类型指针还是父类。
多重继承C#中不支持,只能使用接口才能实现,现在还没学会,留待以后补全。
执行子类的构造函数时,会自动先执行父类的构造函数,当父类中的构造函数为无参时,子类也为无参,当父类中构造函数为有参构造函数时,子类需要添加如下所示
//父类中 public Person(int b) { Console.WriteLine("A构造"); } //子类中 public Chinese():base(1) { Console.WriteLine("B构造"); }
子类中的构造函数既可以有参也可以无参。而如果Person还有父类,则会先调用Person的父类的构造函数。构造函数调用总是从最年长的开始调用,即最老的父类。protected的函数只能在子类及自己中调用,主函数中不可调用。
类的组合:当你需要用到某一个类中的部分对象,只需要把需要的对象加入到你的类中即可。
static void Main(string[] args) { Monkey houzi=new Monkey(); houzi.PS=new Person(); houzi.吃香蕉(); Console.ReadKey(); } } class Person//父类 { public string Name { get; set; } public int Age { get; set; } public void 吃饭() { Console.WriteLine("饭好吃"); } } class Monkey//组合,若只想使用一个类中的部分动作,不用继承,而用组合,是让另外一个类帮助你完成这个动作 { public Person PS//定义一个PS为Person类 { get; set; } public void 吃香蕉()//吃香蕉这个动作由Person类中的吃饭完成 { PS.吃饭(); } }
2018.08.06/07