对象和类型文档格式.docx
- 文档编号:21786595
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:68
- 大小:1.79MB
对象和类型文档格式.docx
《对象和类型文档格式.docx》由会员分享,可在线阅读,更多相关《对象和类型文档格式.docx(68页珍藏版)》请在冰豆网上搜索。
C、一些行为及约束条件
3.实例化类型
从某个类型模板创建实际的对象,称为实例化该类型。
1、通过实例化类型而创建的对象被称为类型的对象或类型的实例。
2、在C#程序中,每个数据项都是某种类型的实例。
这些类型可以是语言自带的,可以是BCL或其他库提供的,也可以是程序员定义的。
成员的类别
另一些类型可以包含许多不同类型的数据项。
这些类型中的数据项个体称为成员,并且与数组中使用数字来引用成员不同,这些成员有独特的名称。
数据成员:
保存了与这个类的对象或作为一个整体的类的相关的依据。
函数成员:
执行代码,函数成员定义类型的成员。
非简单预定义类型
Stringunicode字符序列System.String
Object所有其他类型的基类System.Object
Dynamic在使用动态语言编写的程序集时使用
4.用户定义类型:
类(class)
结构(Struct)
数组(array)
枚举(enum)
委托(delegate)
接口(interface)
类型通过类型声明创建,类型声明包含:
要创建的类型种类、新类型的名称、对类型中每个成员的声明(名称和规格,array和delegate类型除外)
一旦声明了类型就能像预定义类型一样创建和使用这种类型的对象
使用用户定义类型必须先声明类型,然后实例化该类型的对象。
栈
运行中的程序使用两个内存区域来存储数据:
栈和堆,存储在哪里依赖于数据类型。
数据先进后出,后进的数据促使栈顶上移,把数据放入栈顶叫入栈,从栈顶删除叫出栈。
栈存储:
某些类型变量的值、程序当前的执行环境、传递给方法的参数
堆
堆可以分配大块的内存用于存储某类型的数据对象。
堆里的内存可以以任意顺序存入和移除。
虽然程序可以在堆里保存数据,但并不能显式地删除它们。
CLR的自动GC(垃圾收集器)在判断出程序的代码将不会再访问某数据项时,自动清除无主的堆对象。
值类型和引用类型
引用类型需要两段内存
1、第一段存储实际的数据
2、第二段是一个引用,指向数据在堆中的存放位置
存储引用类型对象的成员
引用类型的对象的数据部分始终存储在堆里
值类型对象,或引用类型数据的引用部分可以存放在堆里,也能存放在栈里,视实际环境而定。
例如,假设有一个引用类型实例,名称为MyType,有两个成员:
一个值类型成员和一个引用类型成员。
4种变量
名称
类型的成员
描述
本地变量
否
在方法的作用域保存临时数据
字段
是
保存和类型或类型实例相关的数据
参数
用于从一个方法到另一个方法传递数据的临时变量
数组元素
(同类)数据项构成的有序集合的一个成员
变量类型
存储位置
自动初始化
用途
栈或堆栈
用于函数成员内部的本地计算
类字段
类的成员
结构字段
堆或栈
结构的成员
栈
把值传入或传出方法
数组的成员
变量的类型在编译的时候确定并且不能在运行时修改,这叫做静态类型。
变量的类型直到运行时才会被解析。
由于它们是.NET语言所以C#程序需要能够使用这些语言编写的程序集。
程序集中的类型直到运行时才会被解析,而C#又要引用这样的类型并且需要在编译的时候解析类型,正对这个问题,dynamic关键字代表一个特定的、实际的C#类型,他知道如何在运行时解析自身——动态化的静态类型。
C#编译器可以把关键字解析为实际类型,并且类型对象又可以在运行时把自身解析成目标程序集的类型。
可空类型
在某些情况下,特别是使用数据库时,表示变量目前未保存的有效的值。
对于引用类型,可以把变量设置为Null。
但定义值变量时,不管其内存内容是否有效,其内存都会进行分配。
对于这种情况,使用一个布尔指示器来和变量关联,如果值有效,则设置为True,反之设置为false。
可空类型允许创建可以标记为有效或无效的值类型,这样就可以在使用它之前确定值的有效性。
可空类型总是基于另外一个已声明类型,这个类型称为底层类型(任何值类型),要创建可空类型变量,只需要在变量声明中在底层类型的名字后面添加一个问号。
Int?
myInt=28;
和任何变量一样,要获取其值,只需要使用其名字。
要检查可空类型是否包含值,只需要和null比较。
If(myInt!
=null)
Console.Weiteline(“{0}”,myInt);
myInt1=15;
//把int隐式转换为int?
Intregint=(int)myint1;
//把int?
显式转换为int
可以为可空类型的变量赋值三种:
1.其底层类型的值
2.相同可空类型的值
3.Null值
类基础:
随着面向对象的出现,焦点从优化指令转移到组织程序的数据和功能上来。
程序的数据和功能被组织为逻辑上相关的数据项和函数的封装集合简称为类。
类是一个能存储数据并执行代码的数据结构。
类是逻辑相关的数据和函数的封装,通常代表真实世界中的或概念上的事物。
数据成员:
存储与类或类的实例相关的数据。
数据成员通常模拟该类所表示的现实世界事物的特征。
函数成员:
执行代码。
函数成员通常模拟类所表示的现实事物的功能和操作。
一个C#类可以有任意数目的数据成员和函数成员。
成员可以说9种成员类型的任意组合。
字段、常量;
方法、属性、构造函数、析构函数、运算符、索引、事件。
运行中的程序是一组相互作用的类型对象,他们中的大部分是类的实例。
声明类:
类的声明定义新类的特征和成员。
它不创建类的实例,但创建了用于创建实例的模板。
类的声明提供下列内容:
类的名称、类的成员、类的特征。
类成员:
字段和方法是最重要的类成员类型。
字段是数据成员,方法是函数成员。
字段是隶属于类的变量。
可以说无论用户定义类型还是,预定义类型。
C#在类型的外部不能声明全局变量(也就是变量或字段),所有的字段都属于类型,而且必须在类型声明内部声明。
方法:
具有名称的可执行代码块,运用属性。
可以从程序的很多地方执行,甚至从其他程序执行。
还有匿名方法
当方法被调用(call或invoke)时,它执行自己所含的代码,然后返回到调用它的代码。
有些方法返回一个值到调用它的位置。
方法相当于C++中的成员函数。
与C/C++不同,没有全局函数(也就是方法和函数)声明在类型声明的外部。
同样,和C/C++不同,方法没有返回默认类型。
所有方法必须包含返回类型或void。
创建变量和类的实例:
类的声明只是创建类的实例的模板,一旦类被声明就能创建实例。
1、类是引用类型,这意味着它们要为数据引用和实际数据两者都申请内存。
2、数据的引用保存在一个类类型的变量中。
所以,要创建类的实例,需要从声明一个类类型的变量开始。
如果变量没有被初始化,它的值是未定义的。
ClassDealer{….}//声明Dealer类
ClassProgram
{
DealertheDealer;
//声明Dealer类型的变量Dealer;
theDealer=newDealer();
//为类对象分配内存
//DealertheDealer=newDealer();
//适用对象创建表达式初始化变量,声明并初始化
为数据分配内存
声明类类型的变量所分配的内存是用来保存引用的,而不是用来保存类对象实际数据的。
要为实际数据分配内存,需要使用new运算符。
New运算符为任意指定类型的实例分配并初始化内存。
它依据类型的不同从栈或堆里分配。
使用new运算符组成一个对象创建表达式,组成如下:
1、关键字new;
2、要分配内存的实例的类型名称
3、成对的圆括号,可能包括参数或没有参数
NewTypeName()
如果内存分配给一个引用类型,则对象创建表达式返回一个引用,指向在堆中被分配并初始化的对象实例。
使用new运算符创建对象创建表达式,并把它的返回值赋给类变量。
实例成员
类声明相当于蓝图,通过蓝图想创建多少个类的实例都可以。
实例成员类的每个实例都是不同的实体,它们有自己的一组数据成员,不同于同一类的其他实例。
因为这些数据成员都和类的实例相关,所以被称为实例成员。
静态成员实例成员是默认类型,但也可以声明与类而不是实例成员相关的成员,它们被称为静态成员。
ClassDealer{…}
ClassPlayer
StringName;
…
Staticvoidmain()
DealertheDealer=newDealer();
PlayerPlayer1=newPlayer();
PlayerPlayer2=newPlayer();
PlayerPlayer3=newPlayer();
……
}
访问修饰符
从类的内部,任何函数成员都可以使用成员的名称访问类中任意的其他成员。
访问修饰符是成员声明的可选部分,指明程序的其他部分如何访问成员。
访问修饰符放在简单声明形式之前。
字段:
访问修饰符类型标识符;
访问修饰符返回类型方法名()
…
私有访问和公有访问
私有成员只能从声明它的类的内部访问,其他的类不能看见或者访问它们。
公有成员可以被程序中的其他对象访问。
必须使用public访问修饰符指定公有访问。
从类的内部访问成员
类的成员仅用其他类成员的名称就能访问它们。
例如,下面的类的声明展示了类的方法对字段和其他方法的访问。
即使字段和方法被声明为Private,类的所有成员还是都可以被类的任何方法访问。
从类的外部访问成员
要从类的外部访问成员必须包括变量名称和成员名称,中间用(.)——点运算符分隔
例子:
下面的代码声明了两个类:
DaysTemp和Program
DaysTemp内的两个字段被声明为Public
方法main是Program的成员。
它创建了一个变量和类DaysTemp的对象,并赋值给对象字段。
然后读取它的字段并打印出来。
classDaysTemp
publicintheight;
publicintweight;
classProgram
staticvoidmain()
DaysTempbox=newDaysTemp();
box.height=12;
box.weight=20;
Console.WriteLine("
height={0},weight={1}"
box.height,box.weight};
Console.ReadLine();
}
例子:
下面的代码创建两个实例,并把它们保存在名称t1和t2的变量中,这段代码示范了目前为止讨论的使用类的3种行为:
1.声明一个类
2.创建类的实例
3.访问类的成员
classTemp
publicinta,b;
publicintaverange()
intc=(a+b)/2;
returnc;
classProgram
staticvoidMain()
Tempt1=newTemp();
Tempt2=newTemp();
t1.a=12;
t1.b=22;
t2.a=32;
t2.b=42;
Console.WriteLine("
high1={0},low1={1},high2={2},low2={3},averange1={4},averange2={5}"
t1.a,t1.b,t2.a,t2.b,t1.averange(),t2.averange());
Console.ReadLine();
5.方法
5.1方法的结构
方法是一块具有名称的代码,可以使用方法的名称从别的地方执行代码,也可以把数据传入方法并接收数据输出。
方法是类的函数成员。
主要有两个部分:
方法头和方法体。
1、方法头指定方法的特征,包括:
a.方法是否返回数据,如果返回,返回什么类型。
b.方法的名称
c.哪种类型的数据可以被传送并源自方法,以及应如何处理该数据。
2、方法体包含可执行代码的语句序列。
执行从方法体的第一条语句开始,一直到整个方法结束。
方法体内部的代码执行
方法体是一个块,包含:
本地变量,控制流结构,方法调用,内嵌的块。
本地变量
和字段一样,本地变量也保存数据。
字段通常保存和对象状态有关的数据,而创建本地变量经常是用于保存本地或临时的计算数据。
1.本地变量的存在性仅限于创建它的块及其内嵌的块;
它从声明它的那一点开始存在。
它在块完成执行时结束存在。
2.可以在方法体内任意位置声明本地变量,但要在使用它们前声明;
对比实例字段和本地变量
实例字段的生存期:
从实例被创建时开始,直到实例不再被访问时结束。
实例字段可隐式初始化为该类型的默认值
类的所有字段都存储在堆里,无论他们是值类型还是引用类型
本地变量值类型存储在栈里,引用类型存储在堆里。
类型推断和Var关键字
1.只能用于本地变量,不能用于字段
2.只能在变量声明中包含初始化时使用
3.一但编译器推断变量的类型,它就是固定且不能更改的
Var关键字不像JavaScript的Var那样可以引用不同的类型,它是从等号右边推断出的实际类型的速记。
Var关键字并不改变C#的强类型性质。
嵌套块中的本地变量
方法体内部可以嵌套其他的块。
可以有任意数量的块,并且它们既可以是顺序的也可以更深层嵌套的。
块可以嵌套到任意级别。
本地变量可以在嵌套块的内部声明,并且和所有的本地变量一样,它们的生存期和可见性仅限于声明它们的块及其内嵌块。
在C/C++中,可以先声明一个本地变量,然后在嵌套块中声明另一个相同名称的本地变量。
在内部范围,内部名称掩盖了外部名称。
然而,在C#中不管嵌套级别如何,都不能在第一个名称的有效范围内声明另一个同名的本地变量。
Voidmethod()
Intvar1=5;
//变量var1在嵌套块之前声明,在栈中为它分配了空间
Intvar2=10;
//变量var2在嵌套块之内声明,在栈中为它分配了空间
}//当执行传出嵌套块时,var2被从栈里弹出
本地常量
本地常量很像本地变量,至少一旦它被初始化,它的值就不能被改变。
如同本地变量,本地常量必须声明在块的内部。
常量最重要的两个特征如下:
1.常量在声明中必须初始化;
2.常量在声明后不能改变;
在类型前增加关键字const
必须有初始化语句。
初始化的值必须在编译器决定,通常是一个预定义简单类型或由其组成的表达式。
它还可以是null引用,但它不能是某对象的引用,因为对象的引用是在运行时决定的。
本地常量声明在方法块或代码块里,并在声明它的块结束的地方失效
方法调用
可以从方法体的内部调用其他方法。
调用方法时要使用方法名并带上参数列表
1、当前方法的执行在调用点被挂起
2、控制转移到被调用方法的开始
3、被调用方法执行完成
4、控制回到发起调用的方法
返回值
方法可以向调用代码返回一个值。
返回的值被插入到调用代码中发起调用的表达式所在的位置。
1、要返回值,方法必须在方法名前声明一个返回类型。
2、如果方法不返回值,那么它必须声明void返回类型
3、也可以返回用户定义类型的对象。
当特定条件合适的时候,我们常常会提前退出方法以简化程序逻辑
1、可以在任何时候使用下面形式的返回语句退出方法,不带参数
2、这种形式的返回语句只能用于声明为void类型的方法
方法是可以被程序中很多地方调用的命名代码单元,它能把一个值返回给调用代码。
返回一个值的确有用,但是多数情况下需要返回多个值。
还有能在方法开始执行的时候把数据传入方法也会有用。
参数就是允许你做这两件事的特殊变量。
形参
形参是声明在方法的参数列表中而不是方法体中的本地变量。
下面的方法头展示了参数声明的语法。
PublicvoidPrintsum(intx,flaoty)
1、因为形参是变量,所以它们有类型和名称,并能被写入和读出
2、和方法中的其他本地变量不同,参数在方法体的外面定义并在方法开始之前初始化。
但有一种例外,称为output参数。
3、参数列表中可以有任意数目的形参声明,声明须用逗号隔开。
实参
当代码调用一个方法时,形参的值必须在方法的飞马开始执行前被初始化。
1、用于初始化形参的表达式或变量称为实参
2、实参位于方法的调用的参数列表中
3、每一个实参必须与对应形参的类型相匹配,或是编译器必须能够把实参隐式转换为那个类型。
当方法被调用的时候,每个实参的值都被用于初始化相应的形参,方法体随后被执行。
带位置输入参数的方法实例
usingSystem;
namespacesumandaverange
classMyclass
publicintSum(intx,inty)
returnx+y;
publicfloatAvg(floatx,floaty)
return(x+y)/2.0F;
MyclassmyT=newMyclass();
intsomeInt=6;
NewFlash:
Sum:
{0}+{1}={2}"
5,someInt,myT.Sum(5,someInt));
Avg:
5,someInt,myT.Avg(5,someInt));
值参数
使用值参数,通过复制实参的值到形参的方式把数据传递到方法。
方法被调用时,系统做如下操作:
1、在栈中为形参分配空间
2、复制实参到形参
一个值参数的实参不一定是变量。
它可以是任何能计算成相应数据类型的表达式。
例如,下面的代码展示了两个方法的调用。
在第一个方法调用中,实参是float类型的变量,第二个方法中,它是计算成float表达式。
namespaceMyclass
classMyClass
publicintVal=20;
staticvoidMyMethod(MyClassf1,intf2)
f1.Val=f1.Val+5;
f2=f2+5;
MyClassa1=newMyClass();
inta2=10;
MyMethod(a1,a2);
a1={0},a2={1}"
a1.Val,a2);
1、在方法调用前,用作实参的变量a1已经在栈里了
2、随着方法调用开始,系统在栈中为形参分配空间,并从实参复制值
因为a1是引用类型,所以引用被复制,结果实参和形参都引用堆中同一对象
因为a2是值类型,所以值被复制,产生一个独立的数据项
3、在方法的结尾,f2和对象f1的字段被加上了5
方法执行后,形参被从栈中弹出
a2值类型,它的值不受方法行为影响
a1引用类型,但它的值被方法的行为改变了
引用参数
1、使用引用参数时,必须在方法的声明和调用中都使用ref修饰符
2、实参必须是变量,在用作实参前必须被赋值。
如果是引用类型变量,可以赋值为一个引用或null值
下面的代码阐明了引用参数的声明和调用的语法
voidMyMethod(refintval)//方法声明
{...}
inty=1;
//实参变量
MyMethod(refy);
//方法调用
在之前的内容中我们已经认识到,对于值参数,系统在栈上为其分配内存,相反对于引用参数:
1、形参的参数名看起来好像就是实参变量的别名,也就是说它们指向的是相同的内存位置
2、由于形参名和实参名的行为就好像
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 对象 类型
![提示](https://static.bdocx.com/images/bang_tan.gif)