1 类的定义详解
类是一类事物的总称,对象是该类事物的每一个具体的个体;在c#中每个类包含属性、字段方法和事件四个要素,每个要素存在private、public、protected和interanl四种访问属性
一个类的定义必须包含访问属性、class关键字、类名及类的实现,形如:
accessAttri class className {classBody}
1.1 类对象引用的创建与销毁
类变量的定义如下:
1. className obj = new className(paraList); 2. 类名 对象名 new关键字 类的构造函数(形参列表)
类的对象创建通过new关键字实现,新的对象被创建后,就会一直存在;
所有类变量都是指向具体对象的引用,通过这些引用可以访问类中的方法和成员;
对象的引用可以为null,但此时访问类的成员和方法会抛出异常
类对象在使用完毕后,垃圾回收机制会监视该引用对象的引用计数是否为0,若为0,进行垃圾回收。
1.2 类的字段、属性和方法
类的字段即类的成员变量,一般定义为私有,外界对字段的访问通过为其定义的属性进行
类字段的声明:
[AccsePara] [static] [Readonly] DataType fieldName; 访问属性 静态标记 只读标记 字段类型 字段名称
类的字段一般以下划线开头,而对应的访问属性则去掉下划线表示;定义属性的作用是为了避免在类的外部直接对数据进行操作,此外还可以通过属性对字段的赋值过程进行预处理,增强了系统的安全性和类的封装特性。
类的方法用来描述类对象的某种行为,进行数据处理,以实现某种功能。类的方法可以重载,重载函数必须具有不同的参数类型或和顺序,仅返回值类型不同不能构成重载关系;重载函数调用时,调用对象会传入的参数列表匹配最佳的重载版本
public class Animal { //定义动物品种字段 private string _Name; //定义品种属性 public string Name { set {this._Name = Name;} get {return this._Name; } } //定义动物年龄字段 private string _Age; //定义年龄属性 public string Age { set { if(Age > 0 || Age < 100) this._Age= Age;} get {return this._Age; } } //定义方法 public void Shouting() { System.Console.Writeline("Animal shouting ..."); } }
通过类的对象访问属性和字段,采用“ . ”操作符进行
1.3 类成员的访问属性
private相当于一个人自己的私有秘密,不能告诉外人;即只能在类内访问,类外不可访问
protected相当于父子之间的可以共享的而不能告诉别人的秘密;即只能在当前类及其子类访问
internal相当于一个人发朋友圈,他朋友圈的人都知道的秘密;即只能在同一名称空间的其他类访问
public相当于一个拿着大喇叭在大街上大喊大叫,告诉别人的事情;即在类外可以任意访问
1.4 类的构造函数
函数名与类名一致,没有返回值,默认为public且无参数,程序员可以自定义带参数的构造函数
1.5 类的静态成员
使用static关键字修饰的成员,为类的所有对象所共有,不隶属于类的任何单一对象;
没有this,也不允许通过类的对象进行访问,只能使用类名进行访问
2 类的继承与多态
2.1继承
继承的目的是在父子类之间抽象出可统一使用的接口
使用:表示类之间的继承关系,一个类只能有一个父类;不允许多重继承
class subClass : baseClass {}
注意:父类引用可以指向子类对象;但其依旧只能访问其父类的成员,子类特有的成员不可访问。
2.2 多态
即使是同样的行为,在父类和子类之间也可能存在不同的实现;比如狗叫的是“汪汪”,猫叫是“喵喵”,它们都继承自动物类的“叫”这一行为,但表现出了不同的特性。多态就是针对此种情形设计的解决方案,具体实现策略为:在父类中使用virtual关键字定义虚函数;在子类中使用override关键字,对其进行重写。
[AccessAttri] [virtual] [returnType] FuncName(paraList);//父类版本 [AccessAttri] [override] [returnType] FuncName(paraList);//子类版本
子类重写版本必须具有相同的函数原型,包括函数名称、参数列表和返回值类型
在子类中要调用父类版本时,可使用base关键字显式调用父类版本
public class Animal { public virtual void Shouting() { System.Console.Writeline("Animal Shouting ..."); } public virtual void eating() { System.Console.Writeline("Animal eating"); } } public class Cat : Animal { public overridevoid Shouting() { System.Console.Writeline("Cat Shouting ..."); } public overridevoid eating() { base.eating(); } } static void Main() { Animal aml = new Animal(); aml.Shouting(); Cat cat = new Cat(); cat.eating();//调用的是父类的版本 cat.Shouting();//调用的子类自己的版本 }
3 抽象类与静态类
3.1 抽象类的关键要点
如果一个类必须被继承,则该类就被定义为抽象类;
抽象类使用abstract关键字修饰,这样的类不允许被实例化
其继承子类必须实现其所有抽象函数,否则其子类也是抽象类
抽象类可以包含抽象函数,本身不提供任何实现
3.2 静态类的关键要点
使用static关键字修饰,静态类也不能被实例化
所有成员必须为静态且为抽象对象
典型的静态类是System.Math类,所有成员均通过类名调用
4 is和as关键字
is关键字判断某个对象是否为某个类或其父类的对象
refObj is DataType; example: aml is Animal //true dog is Animal //true aml is Dog //false
as关键字进行安全的类型转换,不兼容返回null;待转换对象必须是目标类型或目标类型的派生类
dstObj = refObj as DataType example: dog as Animal //转换成功 aml as Dog //null
5 接口
C#不支持多重继承,但是一个类可以把继承自多个接口,其间使用逗号隔开
接口的定义使用interface关键字,是方法、属性、事件的集合,不提供任何字段
接口不需要提供访问属性,所有成员都是public
如果一个类实现了接口,那么它也是接口类型
实现接口提供了接口定义所有成员的具体实现;若继承自多个接口,则必须提供这些接口的所有实现
interface IAnimal { float Distance { set; get; } float Speed { set; } void Run(); } class Cat : IAnimal { private float _Distance; public float Distance { set {this._Distance = Distance;} get {return this._Distance} } private float _Speed; public float Speed { set {this._Speed = Speed;} get {return this._Speed} } public void Run() { this._Distance = this._Speed; } }
- 接口与抽象类的对比分析