C#知识点:
基础语句
·Console.WriteLine(内容):向控制台(屏幕)输出内容后换行;
·Console.Write(内容):向控制台(屏幕)输出内容后不换行;
输出语句
双引号中的内容为字符串,会按照原样输出在屏幕上,若想输出表达式的值,表达式不能写在引号中,可以用以下两种方式输出:
- 单独用一个Write(表达式)来输出,此时表达式不加引号;
- 利用占位符来输出,每个占位符用{数字}表示,并将占位符放在引号中。
例:
Console.Write(“12+15=”);
Console.WriteLine(12+15);
Console.ReadKey();
Console.WriteLine(“12+15={0}”,12+15);
Console.ReadKey();
数据输入
·Console.ReadLine();从控制台读入一行字符,以回车结束输入。返回字符串;
·Console.Read();从控制台读入一个字符,以回车结束输入。如果输入的是一行字符,返回首字符的ASCII码;
·Console.ReadKey();从控制台读入一个字符或功能键,输入一个字符后自动结束输入,通常用来暂停屏幕。
例:
Console.WriteLine(“请输入你的姓名:”);
String name=Console.ReadLine();
Console.WriteLine(“Hello,{0},欢迎来到C#的世界!”,name);
Console.ReadKey();
数据类型
- 整数类型
名称 | 类型 | 长度 | 储存空间字节数 |
Sbyte | 有符号字节整数 | -128~127 | 1 |
Byte | 无符号字节整数 | 0~255 | 1 |
Short | 有符号短整型 | -32768~-32767 | 2 |
Ushort | 无符号短整型 | 0~65535 | 2 |
Int | 有符号整型 | -2147483648~2147483647 | 4 |
Uint | 无符号整型 | 0~4294967295 | 4 |
Long | 有符号长整型 | -9223372036854775808~9223372036854775807 | 8 |
Ulong | 无符号长整型 | 0~18446744073709551615 | 8 |
整数类型表示没有小数点的整数值(1字节=8位(二进制位))
- 浮点类型
名称 | 类型 | 长度 | 存储空间字节数 |
Float | 单精度 | 精确到7位数 | 4 |
Double | 双精度 | 精确到15~16位数 | 8 |
Decimal | 精确小数类型 | 精确到28位数 | 16 |
浮点类型表示带小数点的数值
年龄byte 圆的面积double 招生人数int 职工工资float 金融decimal
- 布尔类型与字符类型
名称 | 类型 | 长度 | 存储空间字节数 |
Bool | 布尔类型 | True/False | 1 |
Char | 字符类型 | 一个字符 | 2 |
·布尔类型只有两个值:true和false;
·字符类型用于表示一个字符,字符常量用单引号引起来。
- String类型
·string 字符串
是System.String类型的别名,用于表示任意长度的字符串,属于引用类型字符串常量,用双引号引起来。
运算符
- 算数运算符
·算数运算符主要是对操作数进行基本的数学运算,包含一元运算符与二元运算符:
(1)一元运算符:-(取负) +(取正) ++(自加) --(自减)
(2)赋值运算符:+(加) -(减) *(乘) /(除) %(求余)
·二元运算符+(加)、 -(减)、 *(乘)、 /(除)和%(求余),与数学运算符的用法类似,它们的优先级关系与数学运算符也是一致的,即先乘除(求余)后加减,同级运算之间按从左至右的顺序进行运算,即结合方式从左至右。
注:
·C#.NET中的‘+’运算符有两种用法,一种用于计算两个操作数或表达式的和,另一种可作为连接字符的连接符;
·在进行运算时,如果运算符两边操作数的类型不同,则系统会自动转换为相同的类型再进行运算。转换原则是:将低精度的数据转换成高精度的数据参与运算;
·算数运算符产生的结果可能会超出涉及的数值类型可能的取值范围,此时会发生溢出
- 赋值运算符
·符号‘=’就是赋值运算符,使用的一般形式为:变量=表达式;
·它的作用是将赋值号右边的表达式的值赋值给赋值号左边的变量;
·赋值运算符左操作数必须是一个变量,赋值运算符的结果是将一个新的数值(表达式的值)存放在变量所指示的内存空间中,此时变量的值即为表达式的值;
·‘=’是从右向左结合的运算符,即运算顺序自右至左。对变量进行连续赋值时,赋值操作符从右向左被分组;
例:x=y=z等价于x=(y=z)
·当表达式值的类型与被赋值变量的类型不一致,需要将表达式的值换成变量的类型再进行赋值(隐式转换或强制转换)
- 关系运算符
·关系运算符(比较运算符)包括:==、!=、<、>、<=、>=
·关系运算符常用于判断某个条件是否成立,通过关系运算符将两个操作数连接起来,即为关系表达式。关系表达式的结果为bool类型(ture/false)
·<、>、<=、>=运算优先级相同(高)
·==、!=运算优先级相同(低)
- 逻辑运算符
·在C#中逻辑运算符有两类:
- 布尔运算:是!(非)、&&(与)、||(或) 优先级(!>&&>||)
X | Y | !X | !Y | X&&Y | X||Y |
true | true | false | false | true | true |
true | false | false | true | false | true |
false | true | true | false | false | true |
false | false | true | true | false | false |
- 按位运算:~(非)、&(与)、|(或)、^(异或) 优先级(~>&>|>^)
X | Y | !X | !Y | X&&Y | X||Y | X^Y |
1 | 1 | 0 | 0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 0 | 1 | 1 |
0 | 1 | 1 | 0 | 0 | 1 | 1 |
0 | 0 | 1 | 1 | 0 | 0 | 0 |
- 条件运算符
·条件运算符是唯一的三元运算符,它由‘?’和‘:’两个标点符组成,它的3个对象均是表达式
·语法形式如下:<条件>?<表达式1>:<表达式2>;先计算条件的值,如果计算结果为true,则整个表达式的值是表达式1的值;如果计算结果为false,则整个表达式的值是表达式2的值(条件计算的结果必须为bool型,否则会出错)
·条件运算符的优先级仅优先于赋值运算符
·条件运算符的结合方向为“自右至左”
- C#运算符优先级
运算符 | 优先级 |
初级运算符 | ()、++、--、new、checked、unchecked |
一元运算符 | +、-、!、~、++、--、类型转化运算符 |
乘除运算符 | *、/、% |
加减运算符 | +、- |
移位运算符 | <<、>> |
关系运算符 | <、>、<=、>=、is、as |
位运算符 | &、|、^(这里从左到右,优先级依次降低) |
布尔运算符 | &&、|| |
三元运算符 | ?: |
赋值运算符 | =、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>= |
If语句
·第一种形式:简单if语句(单分支结构)
If(表达式)
{
语句
}
- 表达式必须使用圆括号括起来;
- 表达式:关系表达式或逻辑表达式,代表分支的条件;
(3)‘语句’可以是单语句也可以是复合语句
·第二种形式:双分支if语句(if…else…)
If(表达式)
{
语句1
}
Else
{
语句2
}
注:if语句可以进行多层嵌套,这将会出现多个if和多个else重叠的情形,因此要特别注意if和else的配对问题。C#语言规定,else总是与它前面最近的if配对。
·第三种形式:多分支if语句
If()
{语句1}
Else if
{语句2}
……
Switch语句
·Switch结构也是多分支结构,它通过Switch表达式的值与多个不同值进行比较,选择相应的case语句来处理多个选择。
Switch(表达式)
{
Case 常量1:
语句1
Break;
Case 常量2:
语句2
Break;
Defaule:
语句
Break;
}
·Switch后的表达式可以为整型、字符型、字符串和枚举类型
·当表达式的值与case后的常量表达式的值相等时,则执行该case后的语句序列。执行完后退出Switch语句,跳转到整个Switch语句之后的下一个语句执行。如果所有的case语句的常量表达式的值与Switch之后的表达式不匹配,则执行default之后的语句序列
·各case语句之后的常量表达式的值不能相同
·各分支的break语句不能省略
·多个case语句可以共用一组执行语句
While语句
·while(条件表达式)
{
语句
}
先判断,后执行语句,循环体可能一次也不执行;(循环次数0-n)
Do while语句
·do
{
语句
}while(条件表达式);
先执行语句,后判断,循环体最少执行一次;(循环次数1-n)
For语句
·for(表达式1;表达式2;表达式3)
{
语句组
}
- 表达式1:在循环前运行一次,用于赋初值
- 表达式2:关系表达式或逻辑表达式,代表循环的条件
- 表达式3:修改循环变量的值
·使用说明
- 在for语句之前已经给循环变量赋初值,则for语句的循环变量赋初值部分可以省略,但其后的分号不能省略
- 可以将循环变量修正值的工作纳入循环体中去做
- For语句可以三个部分都省略,但省略表达式2会陷入死循环,除非在循环体中有专门的语句跳出循环
Break语句
·break语句通常用在循环语句和开关语句中
- 当break用于开关语句Switch中时,可使程序跳出Switch而执行Switch以后的语句
- 当break语句用于do-while、for、while循环语句中时,可使循环终止转到执行循环之后的语句
- 通常break语句总是与if语句搭配使用,表示满足某条件时跳出循环
Continue语句
·用于终止本次循环,跳过该循环体中位于continue后面的语句,进入下次循环
·用于循环语句中,类似于break语句,常与条件语句一起使用
·区别:
- break语句结束整个循环过程,不再判断执行循环的条件是否成立
- continue语句只结束本次循环,而不是终止整个循环的执行
数组
·数组是一组具有相同类型和名称的变量的有序集合
·组成数组的这些变量成为数组的元素。一个数组中有若干个数组元素
·数组元素在内存中连续存放,每个数组元素都有一个编号,这个编号叫做下标,用来指出猴哥元素在数组中的位置。通过下标可以区分数组中的元素
·数组的下标从0开始。即数组中第一个元素的下标默认为0,第二个元素的下标为1,依次类推
·数组中元素的个数成为数组的长度,如果某一数组有n个元素,则其最大下标为n-1
·数组元素下标的个数成为数组的维数,根据数组的维数可以将数组分为数组和多维数组
一维数组的定义
·一维数组是具有相同数据类型的一组数据的线性集合。一维数组只有一个下标,每个数组元素相当于一个普通变量
·语法格式:
数据类型[] 数组名=new 数据类型符[长度];
例:int[] score=new int[5];
或:数据类型符[] 数组名;
数组名=new 数据类型[长度];
例:int[] score;
Score=new int [5];
·为数组元素赋初值的语法形式:
(1)数据类型符[] 数组名=new 数据类型符[]{初值列表};
(2)数据类型符[] 数组名={初值列表};
二维数组的定义
·二维数组是指具有两个下标的数组元素组成的数组
·语法格式:
数据类型符[,] 数组名=new 数据类型[长度1,长度2];
例:
Double[,] score=new double[2,3];
或者:
数据类型符[,] 数组名;
数组名=new 数据类型符[长度1,长度2];
·为数组元素赋初值的语法形式:
- 数据类型符[,] 数组名=new 数据类型[,]{{初值列表1},…{n}}
- 数据类型符[,] 数组名={{初值列表1},…{初值列表n}}
二维数组的遍历
·访问二维数组中的每一个元素叫二维数组的遍历
获取二维数组的行列长度
- 数组名.GetLength(0) //获取行的长度
- 数组名.GetLength(1) //获取列的长度
面向对象程序设计
·面向对象编程(Object Oriented Programming,OOP):强调“由谁来做”,谁是指对象
以对象为中心,先开发类,得到对象,通过对象之间相互通信实现功能
面向对象的基本概念
·对象:对象是现实世界中实际存在的事物,是构成世界的一个独立单位,它由数据(描述事物的属性)和作用于数据的操作(体现事物的行为)构成一个独立整体
·类:在面向对象的方法中,类是具有相同属性和行为的一组对象的集合,它提供一个抽象的描述,其内部包括属性和行为两个主要部分
·抽象:抽象是通过特定的实例抽取共同特征以后形成概念的过程。抽象化主要是为了使复杂度降低,是面向对象编程思想的本质
面向对象的基本特征
·封装:是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界回到具体实现细节,这就是封装思想
·继承:主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展
·多态:指在一个类中定义的属性和方法被其他类继承后,它们可以具有不同的数据类型或表现出不同的行为
类的定义
对象(object)与类(class)
- 概念
·类:类是对一类对象的抽象,是对对象共同特征的描述;相对对象而言,类似于蓝图,包含方法和数据
·对象:对象是表现现实世界中某个具体的事物是类的实例;使用关键字new创建,对象具有行为
- 关系
可以把类看做模型或设计图,创建类就是创建模型,有了类模型才可以利用它来创建对象
例如:汽车制造厂要生产汽车先要有汽车设计图(定义类),然后根据汽车的设计图纸生产出一辆一辆的汽车(对象),不同的汽车都会有一些共性的功能,它们在描述汽车类的图纸中都会有体现。
·类是对多个对象共同特征的抽象描述,是对象的模板;
·对象用于描述现实中的个体,它是类的实例
- 语法
[访问修饰符] class 类名(大写开头)[:基类名]
{
//数据成员
字段(小写开头;类的成员变量)
//函数成员
方法(大写开头;类的成员方法)
}
·类体:包括类中的所有数据(字段)及对数据的操作(方法)
·字段:是类定义中的数据,也叫类的变量
·方法:定义了对类中相关数据的操作
·封装:面向对象程序设计将数据与对数据的操作作为一个整体,以类的形式进行定义。对用户而言,只需要知道如何使用类,而不必知道如何工作
·访问修饰符:使类或类的成员在不同的范围内具有不同的可见性,用于实现数据和代码的隐藏
- public(公有):访问不受限制,可以被任何其他类访问
- private(私有):访问只限于它所属的类
- protected(保护):访问只限于它所属的类,及该类的派生类
- internal(类访问修饰符的默认值):访问只限于本程序集
- 完整定义类
[访问修饰符] class 类名[:基类名]
{
//数据成员
字段(与类相关的变量)
常量(与类相关的常量)
事件(在发生某些行为时,让对象通知调用方)
//函数成员
方法(与某个类相关的函数)
属性(可以从客户端访问的函数组,访问方式与公共字段类似)
构造函数(实例化对象时自动调用的特殊函数。与类同名,无返回类型,用于初始化字段的值)
析构函数(终结器,释放对象时调用)
运算符索引(允许对象以数组或集合的方式进行索引)
}
·字段:是类定义中的数据,也叫类的变量。如果需要在类定义的多个方法中使用某个变量,该变量应该声明为字段
语法:[访问修饰符] 数据类型 字段名;
·方法:定义了对类中相关数据的操作,是类的函数成员
语法:[修饰符] 返回值类型 方法名([形式参数列表])
{
//方法体
}
对象的创建
·定义好类之后,可以用类来定义对象,然后通过new来实例化对象
语法:
类名 对象名;(定义对象)
对象名=new 类名([实参列表]);
或:
类名 对象名=new 类名([实参列表]);
对象成员的访问
·语法:
- 在类的内部访问:成员名
- 在类的外部访问:对象名.成员名
类的属性
·属性:引用时与字段相似的类函数成员
·通过“属性”用于读取和写入“字段”值。将字段的访问方式定义为private而不是public,避免从类外直接读取和写入字段,以此来提供对类中字段的保护
·使用属性,对输入的数据进行检验
·定义属性
语法:
[访问修饰符] 数据类型 字段名;
[访问修饰符] 数据类型 属性名
{
get {return 字段名;}
set{字段名=value;}
}
只读或只写属性
·根据可访问的类型不同分为3种不同的类型:读/写属性,只读属性,只写属性
·在属性声明中,如果只有get访问器,则该属性为只读属性;
·在属性声明中,如果只有set访问器,则该属性为只写属性;
·两者皆有为读/写属性
构造函数
·构造函数通过new关键字创建对象的时候系统自动调用的,当程序在声明一个对象时,系统就直接调用构造函数。通常用来初始化对象的数据成员
语法:[访问修饰符] class 类名[:基类名]
{
Public 类名([形式参数列表])
{
方法体;
}
其他成员声明;
}
·构造函数是方法名与类名同名的特殊的方法
·不能有返回值,没有void
·一般使用访问修饰符public
·创建类的实例(对象)时自动调用
·用于类的实例(对象)初始化
无参构造函数
·若类中没有声明构造函数,编译器将创建隐形默认构造函数
·若用户声明了构造函数,编译器不再创建默认构造函数
·默认构造函数方法体为空,无参
有参构造函数
·构造函数可以带参数,其语法如下:
[访问修饰符] class 类名
{
[访问修饰符] 类名 (形式参数列表)
{
//构造函数主体
}
}
·访问带参数的构造函数语法
类名 对象名=new 类名(实际参数值)
·上述形式参数列表与实际参数值类型一致,个数一致
方法的定义
·把事先编好用于实现某种特定功能的语句块叫做方法
·每一个用来实现一个特定的功能,方法的名字应反映其代表的功能
·在需要使用到这个功能时可直接调用已编好的方法而不需要再次编写程序
·方法一次定义,多次调用
·C#中的方法必须放在类定义中声明,也就是说,方法必须是某一个类的方法;Main方法是每个C#应用程序的入口点,在启动程序时由公共语言运行时(CLR)调用
·语法:
[修饰符] 返回值类型 方法名(passcal命名法)([形式参数列表])
{
方法体
}
·无参方法:完成一个特定功能,不需要传递数据
[修饰符] 返回值类型 方法名()
{
//方法体
}
注:
若无返回值:返回类型为void。方法体中无return语句,或return后无表达式
若有返回值:
- 语句中必须有return语句
- Return语句的表达式或值与返回值类型一致
·有参方法:通过形式参数将数据传递到方法
[修饰符] 返回值类型 方法名(形式参数列表) //每个参数都要给出类型定义
{
//方法体
}
方法的调用
·方法必须先定义(声明),再被调用
- 无参方法调用:方法名()
- 有参方法调用:方法名(实参列表)
类型 | 调用方法 | 例 |
无返回值(无参) | 方法名(); | Console.ReadKey(); |
无返回值(有参) | 方法名(实际参数); | Console.Write(“--”); |
有返回值(无参) | 变量名=方法名();方法名(); | strName=InputName(); |
无返回值(有参) | 变量名=方法名(实参); 方法名.实参 | Score=ComputeScore(strName); If(vipNames.Contains(strName)); |
方法的重载
·方法的重载是声明两个以上的同名方法,是西安对不同数据类型的相同处理
·方法重载有两点要求:
- 重载的方法名称必须相同
- 重载的方法,其形式参数个数或类型必须不同,否则将出现“已经定义了一个具有相同类型参数的方法成员”的编译错误
重载构造函数
·构造函数重载:一个C#类中可以定义多个构造函数,这些构造函数的参数个数不同,或参数数据类型不同。当创建对象调用构造函数时,会根据参数个数和数据类型自动识别应该调用哪一个方法
类的静态成员
·类可以具有静态成员,例如静态字段、静态方法等。声明静态成员需要使用static修饰符
例:
- 声明静态字段:private static int count=0;
- 声明静态方法:public static int add(int x,int y)
{
Return x+y;
}
//Main方法是静态方法
Public static void Main(string[] args)
{
.......
}
静态成员与实例成员比较
·静态成员示例
在Console类中包含以下方法:
Public static string ReadLine();
Public static void WriteLine(string value);
通过类名来调用:
Console.ReadLine();
Console.WriteLine(name);
·实例成员实例
在Random类中包含以下方法
Public virtual int Next();
Public virtual int Next(int maxValue);
Public virtual int Next(int minValue,int maxValue);
通过对象名来调用:
Random rnd=new Random();
Int num=rnd.Next(5,50);
类型 | 关键字 | 含义 | 类外调用格式 |
静态成员 | Static | 成员属于类、与类相关 | 类名.成员名 |
实例成员 | 无/默认 | 成员与具体实例(对象)相关 | 对象名.成员名 |
静态字段
·静态字段在声明开始就一直存储在内存中,直到整个程序停止
·静态字段被类中的所有对象所共享
例:
Int em1; //实例字段
Static int em2; //静态字段
·静态字段通常用法是跟踪类的对象(实例)存在的数量
静态方法
·静态方法:通过类名.方法名()进行调用
·静态方法只能访问静态字段和静态事件
静态与非静态设计原则
·如何判断一个变量或方法应该是实例的还是静态的?
- 如果一个变量或方法依赖于类的某个具体实例,那就应该将它定义为实例变量或实例方法。
例如:每个长方形都有自己的宽与高,宽与高都依赖于某个具体的长方形。因此width.height就是Rectangle类的实例变量。由于Area方法、Perimeter方法依赖于某个具体的长方形,所以它们是实例方法
- 如果一个变量或方法不依赖与类的某个具体实例,那就应该将它定义为静态变量或静态方法。
例如:在Math类中没有一个方法是依赖一个特定实例的,如Sqrt、Pow,因此这些方法都是静态方法
类成员访问小结:
·在不同类中访问
- 访问静态成员:类名.成员名
- 访问实例成员:对象名.成员名
·在同一个类中访问
- 实例方法访问静态成员:成员名
- 实例方法访问实例成员:成员名
- 静态方法访问静态成员:成员名
- 静态方法访问实例成员:对象名.成员名
继承的概念
·继承被用于程序设计中,在现有类(称为父类或基类)上建立新类(称为子类或派生类)的处理过程即为继承
·继承就是在一个已存在的类的基础上建立一个新的类。已存在的类称为基类(base class)或子类(son class)。派生类从基类获得其已有的特性(包括基类数据成员、属性成员和方法成员等),这种现象就叫继承
·派生类对基类成员加以改造和增加新的成员的过程称为派生
·一个基类可以派生出多个派生类,每一个派生类又可以作为基类再派生出新的派生类
·在C#中是只能直接继承自一个基类,不能多重继承,这限制称为单一继承
·在C#中,所有的类都是通过直接或间接地继承Object类得到的
派生类
·派生类继承基数数据成员、属性成员和方法成员,实现代码重用
·语法:
[访问修饰符] class 类名:基类名
{
类体(类成员声明);
}
派生类构造函数
·在C#中,派生类不会继承基类的构造函数和析构函数
·在创建派生类对象时,先调用基类构造函数,再调用派生类自己的构造函数。析构时顺序相反
·默认调用基类无参构造函数
·使用base关键字调用基类有参构造函数
调用格式: :base(参数列表)
·假设A类是B类的基类,B类是C类的基类,则创建C类对象时,调用构造函数的顺序为,先调用A类的构造函数,再调用B类的构造函数,最后调用C类的构造函数
·类的继承可以传递
成员的隐藏
·类的继承中,派生类继承了基类的所有成员(除构造函数和析构函数外)
·当子类定义的字段与父类字段同名时,子类隐藏父类方法,即在默认情况下,子类使用自己的方法
·在派生类中,声明与基类同名成员时加上关键字new
Base关键字
·base指代一个对象的父类/基类
·base的作用:
- 调用父类构造函数
- 取父类中被子类隐藏了的字段
- 取被子类覆盖了的方法
·base关键字调用语法
- 调用父类字段:base.字段名
- 调用父类构造函数:base(参数列表)
- 调用父类方法:base.父类方法();
This关键字
·this代表当前实例
·this的作用:
- 可以调用本类的非静态方法和字段
- 可以调用自己的构造函数
·this关键字调用语法:
- 调用本类的字段:this.字段名
- 调用本类的方法:this.方法名([参数列表])
- 调用本类的构造函数:this(参数列表)
虚拟方法与方法重写
·在派生类中,可重写基类同名成员(名称、参数和返回值相同)
·对于基类中需要被重写方法,用virtual关键字修饰(虚拟方法)
·对于派生类中的同名方法,用override关键字修饰,并重写方法
方法隐藏与方法重写的区别
类型 | 定义基类方法 | 派生类方法 | 区别 |
方法隐藏 | 不变 | 加new | 基类引用指向派生类对象时,不能访问派生类new方法,默认基类 |
方法重写 | 加virtual | 加override | 基类引用指向派生类对象时,正确访问派生类的override方法 |
·不建议使用隐藏基类方法
·建议在基类用virtual定义虚拟方法,在派生类中用override重写方法
密封类
·密封类:为了阻止一个类的代码被其他类继承,可以使用密封类。达到知识产权的保护,避免他人共享代码
·格式:
Public sealed calss Animal //这是个密封类
{
......
}
则Dog类就无法继承Animal类,其所有代码需要重新书写
抽象类的定义
·抽象类:含有一个或一个以上的抽象成员的类,用abstract进行声明
·抽象类声明格式:
[访问修饰符] abstract class 类名[:基类名]
{
字段
属性
构造函数
方法();
......
Abstract成员(属性 方法 索引 事件)
}
·说明:
- 抽象类中可以包含有一般成员,也可以包含有抽象成员
- 抽象类智能作为基类,它本身不能实例化
·抽象成员:只有声明,无具体实现的隐藏virtual类成员
·抽象方法声明格式:
访问修饰符 abstract 返回类型 方法名([参数列表]);
·抽象属性声明格式:
访问修饰符 abstract 数据类型 属性名
{
Get;
Set;
}
·方法声明格式:
访问修饰符 返回类型 方法名([参数列表]);
{
方法体
}
·属性声明格式:
访问修饰符 数据类型 属性名
{
Get{//获得属性的代码}
Set{//设置属性的代码}
}
接口的定义
·类只允许单继承,接口可以实现多继承
·接口声明格式:
[访问修饰符] interface 接口名[:接口1,接口2,......]
{
抽象成员(属性 方法 索引 事件)
}
·一个类可以实现多个接口,在:后列出需要实现的接口名
·如果派生类不是abstract类型,那么派生类要实现接口的所有抽象方法
·在类中实现接口的抽象方法中,必须与接口中定义的方法名完全一致,即方法名、返回值类型及形参列表要完全一致(不能加override)