[音乐]
那么在前面的学习当中,我们主要已经讲过了数组
方法这两节问题的讨论,也讨论了枚举跟结构。
在下面的学习当中,我们将要好好地再来讨论一下 面向对象的编程。
那么我们从类开始,再一次的、 认真的、 严肃的讨论一下类 Class。
那么我们知道 类是现在我们面向对象编程的一个基石
我们在分析一个问题的时候,会把它抽象成一个一个不同的类
然后在解决的,在使用类的时候,我们会根据类创建出来实例,然后调用实例的方法
把这样的一个东西怎么样呢?问题求解出来,这是面向对象编程的这样的一个基本思想 而我们又知道,C
sharp是一个纯面向对象的编程语言 那就意味着所有的变量、
字段、 属性、 方法等等 都要封装在一个类里面,不会存在着在类之外的
这样的一些方法,或者这样的一些属性等等。
那么,对于类来讲,它是面向对象的编程的
之一的一个重要手段,就是把数据跟方法封装到一起
形成一个完整的这样的一个新的类型 称之为这样的一个类,那么对于类里面的方法来讲
它可以直接访问它自己在类,同样的类里面的字段的值
或者属性的值,而不受到任何的限制,而通过这样的一个封装 把这样的一个类的东西,跟外边进行了一个隔绝。
那么只有public的东西可以从外部来访问,而private的东西怎么样呢?
只能供内部的人来访问,那么这样就有效的保护了
自己的方法和自己的数据,使得我们的程序怎么样呢?更加的安全一些。
那么总的来说,在类里面主要有这样的三个东西,第一个就是字段
也就是说,我们定义的一些常量、 变量等等。
那么还有第二个就是我们前面讲过的属性,就是在我们的 这个课的前一个计算机基础的课里面,C
sharp基础入门里面已经提到过的属性。
那么第三个主要的东西就是方法。
其中字段跟属性都是用来存储一个对象的状态的
这样的一些数据的,而提供的方法怎么样呢?是用来处理这些数据的
在每一个字段属性或者方法前面我们都要有一个
访问的控制,跟类相关的最基本的访问控制一共是三个,public,private和
protected,此外还有一个跟程序级相关的一个访问控制,internal。
那么在我们的 今天的这一次的这样的一讲里面,我们只讨论这样的public跟private的访问控制
protected的访问控制,那是在类的继承里面要讨论的,我们马上就会用到。
在前面的很多学习当中,我们已经看到了所谓public的访问控制
就是指的可以从类的外部直接访问public修饰的字段、
属性 或者方法,所谓从类的外部直接访问的意思就是可以使用
实例名或者对象名.方法或者实例名对象名.
属性.字段的方法可以直接怎么样呢? 来读取它、
存储它或者调用它,比如讲看幻灯片的 假设我们xx是某一个类的实例
或者说xx是根据某一个类创建出来的对象。
那么xx.a等于20,我们不难推测出来 这个a可能是一个属性或者是一个字段
而xx.foo();那么我们也可以看到 这个foo可能应该是一个方法的调用。
不管是如何 在这里面a和foo必须是public的,才能允许直接使用
xx.a或者xx.foo的方式来调用或来使用它
也就是说,凡是public的字段和这样的一个方法是整个类
对外的一个公开的接口,可以供外部使用这样的一个类的
程序或者代码来调用它,直接访问它。
如果这样的一个字段是private的话,那么就不能够 使用xx.a或者xx.foo的方式
来调用和使用字段或者方法,private所修饰的字段、
属性还有方法 都只能供类的内部的函数来使用
当然特别要注意的是,public和private都是指的
对外而言的区分,对类的内部的函数来讲或者方法来讲
那么不管是 字段也罢,属性也罢,方法也罢,对类的内部来讲
是不存在什么public和private的,大家都可以无限制的,直接地使用。
呃,另外稍微说明一下,我们在
我的这样的一个讲课里面,可能有时候会把方法跟函数这两个词是混用的
那么在我的这样的一个所有的,包括后面的讲述里面,方法和 函数是怎么样?是等同的。
函数是c++的说法, 和其他的一些语言的说法,那么方法还有这样的一个method
这样的,是C sharp还有VB等等式说法,其实其本质是怎么样呢?是一回事。
所以说我们方法跟函数这两个名词有时候在,我在不太注意的情况下是混用的
那么在这样的一个,在这样的一个类里面
可以有组合,根据我们的需要设计不同的字段,来存储设计
设计不同的属性来表示这样的一个对象的状态。
设计不同的方法来处理这些
字段的值或者属性的值等等来完成一些功能。
但是这里面有一些特殊的方法是起到特殊的 作用的,其中一个方法就叫做构造函数
构造函数或者叫做构造方法 那么构造函数跟构造方法这样的一个东西
因为这个东西最初当然是从
面向对象的c++那边或者其他语言过来的,所以说很多时候我们还是习惯
的称它为构造函数,当然你也可以把它称之为构造方法。
不管怎么说,它是一个构造的方法,那么这样的一个方法有一个什么特殊性的呢?
首先,这样的一个方法的特殊性是在于该方法的名字和
类名是完全一样的,也就是说如果有一个方法它的类名
它的这个方法名和类的名字是完全一样的话,那么这个方法
就要被特殊的对待,这个方法称之为构造方法或者 更加通用一些,我们称为构造函数。
那么第二个特殊之处,凡是构造方法跟构造函数
不应该声明其任何返回类型的值
那么这句话的意思就是说,如果我们创建了一个普通的方法的话
正确的声明格式应该是在我们方法那节所讲的,应该是访问修饰符public或者pri- vate
紧跟在后面应该是方法的返回值类型,比如讲int,即使是没有返回值
也有一个void对不对?或者还有一个double等等返回值,下来才是方法名,但是
构造函数不一样,构造函数是访问控制public完了之后
直接就是方法名,这中间没有任何的返回值
类型的声明,就是访问修饰符,方法名,方法的参数 列表,是这样的一个过程。
构造函数可以有多个,它是可以重载的 可以根据也就是说,也就是说我们可以怎么样呢?
可以声明多个不同的构造函数,具有相同的名字
那么只要它的这样的一个参数的列表能够区分开来
就可以,换言之,我们可以通过不同的方法来构造一个对象。
那么构造函数是起什么作用的呢?构造函数的作用是
在创建一个对象的时候
将由系统,这个系统一般是指的操作系统,将由系统
或者说我们的.NET框架系统,将由系统自动 调用构造函数一次,且仅一次
永远不允许自己主动的去调用构造函数,
那么也就是说,构造函数的意思就是,
写到那,是供系统调用的,而不是供你自己显示的,
明显的去调用的,由系统在根据这个类创建这个对象实例的时候
会自动地调用这个构造函数。
其次,如果你没有在 一个类里面没有提供构造函数的话,
那么 CSHARP 编译器会为你自动添加一个 缺省的构造函数,该构造函数
不带有任何参数,并且该函数也是一个,或者该方法是一个
空的方法,就是说是不干任何事情的东西,也就是说一旦调用立刻就返回了,什么都不干。
但是,仍然会添加了这样的一个缺省, 添加了这样的一个缺省使得就是什么呢,使得我们这样是统一的,
也就是什么统一了呢?在创建一个对象的时候,
必须要调用构造函数, 必须会调用构造函数,但同时也请记住,构造
函数是由系统调用的,而不是由自己显示调用的。
同时还要明白,在创建一个对象的时候,构造函数只会调用一次,
即使你提供了多个构造函数,也只会
从中选择一个相匹配的构造函数 进行调用一次。
那么构造函数 一般就用来在做一些初始化的工作。
特别是我们知道,在很多时候编程我们容易犯的一个 错误就是忘了给某些变量赋初值,进行初始化,
等等等等,导致后面的一系列问题的存在,而这些问题又难以 查找出来。
那么有了构造函数了之后,我们可以 把这样的对一些变量呀,字段呀还有一些属性的初始化的工作
放到构造函数里面,那么一旦根据这样的一个类创建这样的一个对象,
构造函数就会被系统自动的调用,这样子我们就不用担心什么事情而漏过了,而错过了没有做。
那么有构造
函数,那么还有一个跟构造函数相对的叫做 析构函数。
析构函数的函数名仍然 也是类名,只不过在类名前面多了一个一弯的记号,
就是一个一弯,这样的一弯的符号,因此如果一个 方法它的方法名是一弯加上类名的话,
那么这样的一个方法是有特殊含义的,它叫做
析构函数,或者析构方法。
那么析构函数,那么从它的名字很容易推断出来 那么就是说当这个对象被销毁的时候,
这个析构函数会被调用,而跟构造函数一样,
析构函数也是由系统在对象被销毁或者释放的前一瞬间
由系统自动调用的,并且系统保证调用析构函数。
那么同样的, 同样的,如果你没有给出这样的一个析构
函数的话,那么系统也会给你添加一个缺省的这样的一个析构函数。
那么这个析构函数也是一个什么事情都不干的析构函数。
所以当一个对象被释放的时候,析构函数总归会被调用的,那么跟构造函数不同的是
析构函数不能带有任何函数的参数,也就是说析构函数总是一个不带参数的函数。
因为析构函数是一个不带参数的这样的一个 方法,或者这样的一个函数的话,那么它就没有办法重载,因为它只有一种形式,
不带参数,而我们知道,重载是根据什么呢?是根据我们的这个
参数的形式来区别的。
那么所以说析构函数没有重载,它也不带参数,
那么也就是说整个类,或者整个对象只有一个析构函数。
构造函数跟析构函数都不能够被继承,继承我们会在下一次课里面讲到。
那么我们可以通过不同
的方式来使得这样的一个对类的
类里面的东西进行初始化,那么譬如讲我们可以在类的,写类的
字段的时候,可以直接给类怎么样呢?赋一个
初值,也可以在构造函数里面给类怎么样呢?赋一个初值,
也可以使用什么呢?叫做对象初始化器的这样一个东西
在声明类的时候,使用和数组相同的
或者相类似的方法给怎么样呢?给类作为一个初值的
赋一个初值,那么这几种方法都是给类里面的成员赋初值的方法。
我们会在后面的例题里面详细的讲述跟比较一下这些方法,
那么在类里面我们这边还要讲述的一个事情就是, readonly
这样的一个变量, 介绍的一个 readonly
这样的一个修饰符, 那么如果要在类里面定义的一些变量的话,
那么其值会在构造函数里面,我们会把它放在构造函数里面去初始化,
而初始化之后怎么样呢?就不能修改,我们一般把这样的
如果希望创建一个这样的一种类型的变量或者字段或者属性的话, 我们怎么样呢?我们可以把这样的一个
字段或者属性或者变量声明为 readonly
关键字,用 readonly 关键字怎么样呢?进行修饰。
譬如讲,private readonly int INCREMENT,就如同幻灯片上这样提示的这样
定义了一个只读型整数变量 INCREMENT,那么着重要
注意一下,readonly 和常数 const 有什么区别?
对于常数 const 来讲,一个 const 型的变量定义到类里面,
当把一个变量或者字段定义 为 const
的时候,就必须要立刻给这样的一个 变量或者字段或者属性怎么样?赋一个初值,
那么也就是说,不能够在构造函数里面为不同的 const
型变量赋不同 的值,换言之,所有类,根据这个类创建出来的对象
都拥有同样的一个常数值, 所有的常数值是一样的,而
readonly 怎么样呢?readonly 允许
不同的对象拥有不同的 readonly
修饰 的这样的一个字段的值,也就是说我们可以为 readonly
修饰的变量赋 在不同的对象里面赋上不同的值, 但是每个值只能在构造函数里面赋一次,
一旦定下来了之后,在以后的程序里面就不能够再改,它就是一个只读变量。
所谓只读变量跟常数的区别,简单的就是说
可以在不同的对象里面为
只读变量赋不同的值,一旦赋值之后,就不允许再改。
对于常数来讲,所有的对象,根据这个类 创建出来的所有对象,拥有相同的常数的值。
那么这一讲我们就先说到这, 下面是例题。