4、是先有的蛋,还是先有的鸡?
(去往碰碰凉的路上,实在是无聊,就出现了下面的话题……)
小色:你说是先有的蛋还是先有的鸡?(实在是没话题了,记得曾经问过奶牛下的小牛是不是也是奶牛的这个问题被朋友鄙视了半天,可是到最后也没有讨论出个结果来,唉……都是城市的孩子们啊!)
小力:先有的鸡吧!
(中国语言博大精深,上面那句话纯属测试读者人品,如果骂笔者是下流的,说明淫者见淫。如果看完现在这段话又返回去重新看上面那句话有大彻大悟的的感觉继而骂我的,说明人品有待发展。如果现在依然不知所云的,恭喜你,现在像你这样的人真的是越来越少了,赶快还俗吧!)
小色:没有蛋哪来的鸡呢?
小力:可能鸡在以前也是水生的,然后转而陆生,然后才会下蛋的呢?以前老师不是说过动物的发展是由水生到陆生,由低级到高级的吗?
(这个MM还算是理性,因为曾经有人回答过说鸡也信奉着一个上帝,然后鸡上帝捏了一公一母两只鸡,一只叫鸡当,另一只叫鸡娃,汗……)
小色:也对,我也这么觉得。那你说刚才我的那个对象,如果说姓名,体重,身高都是后天才赋予的,我们可以以赋值的方式来设置,那性别总不能也是后天赋予的吧(但是现在,一切皆有可能,Anything Is Possible)
小力:对啊,性别是人出生的时候就决定好的,怎么能是在后天被赋予呢?哦,我明白了,你的意思是,刚才咱们在让你的对象做介绍的时候,性别是在之前我们给设置的,这样就不符合逻辑了。如果要改的话,也就是说要从对象创建的时候就给它规定好,就好像有了出厂设置一样。
小色:对啊,如果是你的话,你会怎么做?
小力:首先,我会将sex变量设置为私有的,增加Sex属性,只允许get而不允许set。可是既然不能set,那要怎么才能给她初始值呢?如果说在建立对象的时候就要赋值的话,也只有new的时候了。假如说在实例化的时候也能像参数一样把性别传递进去的话,那就好了。
小色:想的不错,那你有没有注意看看实例化的时候new后面的是什么呢?
(边说边进了碰碰凉,然后要了份酸梅汤,点了个圣代,从后脑勺掏出笔记本电脑继续看着代码。)
小力:Girl lili=new Girl( ); 里的Gir( )好像跟我们刚才调用的Cook( )方法样子很类似哦。
小色:娘娘慧眼啊(有点夸张了……),其实我们在实例化的时候,调用的Girl( )叫做构造方法,也叫做构造函数,虽然我们在Girl这个类中并没有明显的(显式)构造方法声明出来,但是其实C#已经为我们提供了一个没有参数,没有返回值的默认构造方法。构造方法的名称必须与类名相同且没有返回值。如果将它用代码写出来,就是这个样子的
默认的构造方法 |
带参数的构造方法 |
class Girl { public Girl( ) { //构造方法块 } } |
class Girl { public Girl(参数列表) { //构造方法块 } } |
小力:看起来和方法是挺像的,就是没有类型和返回值了而已。
小色:而且调用构造方法不是通过点运算符,而是通过new关键字,而且只能在创建对象的时候调用。那我把刚才的代码修改一下,你再看看:
//测试类: using System; class Program { static void {//程序主入口 Girl lili = new Girl(‘女’);//修改1,实例化一个对象的同时传入参数 lili.name = “莉莉”;//给实例变量姓名赋值,注意string类型使用双引号 lili.Age = 23;//给实例变量年龄赋值 lili.high = 168;//给实例变量身高赋值 lili.weight = 105;//给实例变量体重赋值 lili.Age = 23;//给实例变量年龄赋值 lili.Introduce();//调用自我介绍方法 lili.Cook();//调用做饭方法 Console.ReadLine();//等待用户输入内容再结束程序,否则窗口将瞬间消失 } } |
//Girl类: using System; class Girl { public string name;//字符串型,用来保存姓名 public uint high;//无符号整型,用来保存身高 public int weight;//有符号整型,用来保存体重 private int age;//有符号整型,用来保存年龄 public Girl(char sex) {//构造方法。通过构造方法的参数传递,来给Sex属性赋值 this.Sex = sex; } private char sex;//改为私有变量,用来保存性别 public char Sex {//性别属性 get { return sex; }//在外部和内部都可以调用访问器 private set { sex = value; } //私有设置器,只能在本类中调用修改器 } public int Age { get { return age; } set { if (value > 0 && value < 100) { age = value; } else { age = 18; } } } public void Cook() {//定义做饭方法 Console.WriteLine("红豆,大红豆,芋头~~ 锉锉锉锉……"); } public void Introduce() {//定义自我介绍方法 Console.WriteLine("我叫:{0},性别{1},今年{2}岁,身高{3}cm,体重{4}斤", name, this.Sex, age, high, weight); } } |
在Girl类中的构造方法中,有一个this关键字,它是引用类的当前实例,用来在非静态块内调用当前实例中的数据,
运行后的结果:
我叫:莉莉,性别女,今年23岁,身高 红豆,大红豆,芋头~~ 锉锉锉锉…… |
小力:恩,使用的时候跟方法作用看起来一样,只不过方式有点不同,而且这个只能在实例化对象的时候调用一次。可是,如果我依然只想调用不带参数的构造方法new Girl ( ),怎么就报错了呢:
Girl方法没有采用“
(MM边说着边自己改起了代码……)
小色:因为你自己写了一个带参数的构造方法,所以C#认为你已经不需要它提供的默认构造方法了,所以报错了。如果,还想用到无参的构造方法,此时需要显式的声明。也就是需要加入代码
小力:恩,我看到了,那我总结一下构造方法的特点啊:
1、 与类名相同 2、 没有返回值 3、 使用NEW关键字来调用 4、 总是public类型 5、 若被重载,则默认构造函数将消失,必须显式声明 6、 不要做初始化以外的事情 |
小色:所以现在你再想想,是先有鸡还是先有蛋啊?
小力:在C#中鸡和蛋都是对象,你先实例化的鸡,就是先有鸡,先实例化的蛋,就是先有蛋呗。假如在实例化的时候就传递了鸡的性别,那公鸡还是母鸡也就确定了。我这么说对吧!
小色:对,对~~老板,再来一杯酸梅汤!(笔者十分喜欢喝酸梅汤,便宜又好喝!)
完稿日期: