Top Banner
Information Engineering Department of SCEMI .NET .NET 平平平 平平平 C# C# 平平 平平 信信信信信 信信信
29

.NET 平台和 C# 编程

Jan 04, 2016

Download

Documents

aidan-patel

.NET 平台和 C# 编程. 信息工程系:罗明刚. 第六章. 属性、索引器、委托和事件. 回顾. 继承是获得现有类的功能的过程 创建新类所根据的基础类称为基类或父类,新建的类则称为派生类或子类 base 关键字用于从派生类中访问基类成员 override 关键字用于修改方法、属性或索引器。 new 访问修饰符用于显式隐藏继承自基类的成员 抽象类是指至少包含一个抽象成员(尚未实现的方法)的类。抽象类不能实例化 重写方法就是修改基类中方法的实现。 virtual 关键字用于修改方法的声明 显式接口实现是用于在名称不明确的情况下确定成员函数实现的是哪一个接口. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: .NET 平台和 C# 编程

Information Engineering

Department of SCEMI

.NET.NET 平台和平台和 C#C# 编程编程

信息工程系:罗明刚

Page 2: .NET 平台和 C# 编程

Information Engineering

Department of SCEMI

第六章

属性、索引器、委托和事件

Page 3: .NET 平台和 C# 编程

3

Information Engineering

Department of SCEMI 回顾 继承是获得现有类的功能的过程 创建新类所根据的基础类称为基类或父类,新建的类则称

为派生类或子类 base 关键字用于从派生类中访问基类成员 override 关键字用于修改方法、属性或索引器。 new 访

问修饰符用于显式隐藏继承自基类的成员 抽象类是指至少包含一个抽象成员(尚未实现的方法)的

类。抽象类不能实例化 重写方法就是修改基类中方法的实现。 virtual 关键字用

于修改方法的声明 显式接口实现是用于在名称不明确的情况下确定成员函数

实现的是哪一个接口

Page 4: .NET 平台和 C# 编程

4

Information Engineering

Department of SCEMI 目标理解属性及其不同的类型、实现理解和使用索引器实现委托定义和触发事件

Page 5: .NET 平台和 C# 编程

5

Information Engineering

Department of SCEMI 属性简介 3-1

class Employee{

private static string _name;private static string _id;static void Main(string[] args){

_name = Console.ReadLine();_id = Console.ReadLine();

}}

• 直接访问字段• 不经验证 • 直接访问字段• 不经验证

Page 6: .NET 平台和 C# 编程

6

Information Engineering

Department of SCEMI 属性简介 3-2

class Employee{ private static string _name; private static string _id; public void SetId(value) {

// 验证输入长度小于 2if (_id.Length > 2)_id = value;

} public string GetId() {

return _id; }} 方法 SetId(Value) 和 GetId() 分别读取和写入职员 ID方法 SetId(Value) 和 GetId() 分别读取和写入职员 ID

…• Employee emp;• emp.SetId("A1");• string Department = emp.Get() …

…• Employee emp;• emp.SetId("A1");• string Department = emp.Get() …

每次都调用 GetId() 和 SetId()方法会很繁琐

每次都调用 GetId() 和 SetId()方法会很繁琐属性属性

Page 7: .NET 平台和 C# 编程

7

Information Engineering

Department of SCEMI 属性简介 3-3class Employee{ private static string _name; private static string _id; public string Id {

get {

return _id; }

set{

// 验证输入长度小于 2if (_id.Length > 2)_id = value;

} }

}

读取 ID 时调用

将值赋给 ID 时调用

Page 8: .NET 平台和 C# 编程

8

Information Engineering

Department of SCEMI 属性类型 4-1

[ 访问修饰符 ] 数据类型 属性名 {

get{ }; set{ };

}

读 / 写属性读 / 写属性

可以赋值和检索值

Page 9: .NET 平台和 C# 编程

9

Information Engineering

Department of SCEMI 属性类型 4-2

[ 访问修饰符 ] 数据类型 属性名{

get{ };

}

只读属性只读属性

只能检索值

Page 10: .NET 平台和 C# 编程

10

Information Engineering

Department of SCEMI 属性类型 4-3

[ 访问修饰符 ] 数据类型 属性名{

set{ };

}

只写属性只写属性

只能赋值

Page 11: .NET 平台和 C# 编程

11

Information Engineering

Department of SCEMI 属性类型 4-4

[ 访问修饰符 ]static 数据类型 属性名{

get{};set{};

}

静态属性静态属性

应用于整个类而不是类的实例

只能访问类的静态成员

Page 12: .NET 平台和 C# 编程

12

Information Engineering

Department of SCEMI

class SavingsAccount{

// 类字段用于存储帐号、余额和已获利息private int _accountNumber;private double _balance;private double _interestEarned;// 利率是静态的,因为所有帐户获得的利息相同private static double _interestRate;// 构造函数初始化类成员public SavingsAccount(int accountNumber, double balance){

this._accountNumber = accountNumber;this._balance = balance;

}

// 只读 AccountNumber 属性public int AccountNumber{

get{

return _accountNumber;}

}

演示……演示……

定义和调用属性 4-1

只读属性

Page 13: .NET 平台和 C# 编程

13

Information Engineering

Department of SCEMI 定义和调用属性 4-2static void Main(string[] args){

// 创建 SavingsAccount 的对象SavingsAccount objSavingsAccount = new SavingsAccount(12345, 5000);;Console.WriteLine(" 输入到现在为止已获得的利息和利率 ");objSavingsAccount.InterestEarned =

Int64.Parse(Console.ReadLine());SavingsAccount.InterestRate =

Int64.Parse(Console.ReadLine());

objSavingsAccount.InterestEarned += objSavingsAccount.Balance * SavingsAccount.InterestRate;Console.WriteLine(" 获得的总利息为: {0}",

objSavingsAccount.InterestEarned);}

public double InterestEarned{

get{

return _interestEarned;}set{

// 验证数据if (value < 0.0){

Console.WriteLine(“ 利息 不能为负数 ");

return;}

_interestEarned = value;}

}

将设置 InterestEarned 属性

Page 14: .NET 平台和 C# 编程

14

Information Engineering

Department of SCEMI 定义和调用属性 4-3static void Main(string[] args){

// 创建 SavingsAccount 的对象SavingsAccount objSavingsAccount = new SavingsAccount(12345, 5000);;Console.WriteLine(" 输入到现在为止已获得的利息和利率 ");objSavingsAccount.InterestEarned =

Int64.Parse(Console.ReadLine());SavingsAccount.InterestRate =

Int64.Parse(Console.ReadLine());

objSavingsAccount.InterestEarned += objSavingsAccount.Balance * SavingsAccount.InterestRate;Console.WriteLine(" 获得的总利息为: {0}",

objSavingsAccount.InterestEarned);}

将设置 InterestRate 属性

public static double InterestRate{

get{

return _interestRate;}set{

// 验证数据if (value < 0.0){

Console.WriteLine(“ 利率不能为负数 ");return;

}else{

_interestRate = value / 100;}

}

Page 15: .NET 平台和 C# 编程

15

Information Engineering

Department of SCEMI 定义和调用属性 4-4static void Main(string[] args){

// 创建 SavingsAccount 的对象SavingsAccount objSavingsAccount = new SavingsAccount(12345, 5000);;Console.WriteLine(“ 输入到现在为止已获得的利息和利率 ");objSavingsAccount.InterestEarned =

Int64.Parse(Console.ReadLine());SavingsAccount.InterestRate =

Int64.Parse(Console.ReadLine());

objSavingsAccount.InterestEarned += objSavingsAccount.Balance * SavingsAccount.InterestRate;Console.WriteLine(" 获得的总利息为: {0}",

objSavingsAccount.InterestEarned);}

将检索 Balance 和 InterestRate 属性将检索 Balance 和 InterestRate 属性

public double Balance{

get{

if (_balance < 0)Console.WriteLine(" 没有可用余额 ");return _balance;

}}

public double Balance{

get{

if (_balance < 0)Console.WriteLine(" 没有可用余额 ");return _balance;

}}

Page 16: .NET 平台和 C# 编程

16

Information Engineering

Department of SCEMI 索引器

[ 访问修饰符 ] 数据类型 this[ 数据类型 标识符 ]{

get{};set{};

}

语法语法

Page 17: .NET 平台和 C# 编程

17

Information Engineering

Department of SCEMI 定义和调用索引器 4-1

演示……演示……

class Photo{

string _title;public Photo(string title){

this._title = title;}public string Title{

get{

return _title;}

}}

以 Title 属性表示照片将照片存放于数组 photos 中

class Album{

// 该数组用于存放照片Photo[] photos;public Album(int capacity){

photos = new Photo[capacity];}

Page 18: .NET 平台和 C# 编程

18

Information Engineering

Department of SCEMI 定义和调用索引器 4-2public Photo this[int index]{

get{

// 验证索引范围if (index < 0 || index >= photos.Length){

Console.WriteLine(" 索引无效 ");// 使用 null 指示失败return null;

}// 对于有效索引,返回请求的照片

return photos[index];}set{

if (index < 0 || index >= photos.Length){

Console.WriteLine(" 索引无效 ");return;

}photos[index] = value;

}}

带有 int 参数的 Photo 索引器

读 / 写索引器

Page 19: .NET 平台和 C# 编程

19

Information Engineering

Department of SCEMI 定义和调用索引器 4-3

public Photo this[string title]{

get{

// 遍历数组中的所有照片foreach (Photo p in photos){ // 将照片中的标题与索引器参数进行比较 if (p.Title == title) return p;}Console.WriteLine(" 未找到 ");// 使用 null 指示失败return null;

}}

带有 string 参数的 Photo 索引器

只读索引器

Page 20: .NET 平台和 C# 编程

20

Information Engineering

Department of SCEMI 定义和调用索引器 4-4static void Main(string[] args){

// 创建一个容量为 3 的相册Album friends = new Album(3);// 创建 3 张照片Photo first = new Photo("Jenn");Photo second = new Photo("Smith");Photo third = new Photo("Mark");// 向相册加载照片friends[0] = first;friends[1] = second;friends[2] = third;// 按索引检索Photo obj1Photo = friends[2]; Console.WriteLine(obj1Photo.Title);// 按名称检索Photo obj2Photo = friends["Jenn"]; Console.WriteLine(obj2Photo.Title);

}

Page 21: .NET 平台和 C# 编程

21

Information Engineering

Department of SCEMI 委托

Multiply(int,int){….

}

Divide(int,int){….

}

在运行时确定调用哪种方法在运行时确定调用哪种方法

委托和方法必须具有相同的签名

---public delegate Call(int num1, int num2);---

Page 22: .NET 平台和 C# 编程

22

Information Engineering

Department of SCEMI 定义委托 2-1

[ 访问修饰符 ] delegate 返回类型 委托名 (); [ 访问修饰符 ] delegate 返回类型 委托名 ();

语法语法

class Delegates{ public delegate int Call(int num1, int num2); class Math { public int Multiply(int num1, int num2) { // 实现 } public int Divide(int num1, int num2) {// 实现 } }class TestDelegates{ static void Main() {

Call objCall; Math objMath = new Math();

objCall = new Call(math.Multiply); }}

将方法与委托关联起来将方法与委托关联起来

Page 23: .NET 平台和 C# 编程

23

Information Engineering

Department of SCEMI 定义委托 2-2class Delegates{

// 委托定义public delegate int Call(int num1, int num2);

class Math{

// 乘法方法public int Multiply(int num1, int num2){

return num1*num2;}

// 除法方法public int Divide(int num1, int num2){

return num1/num2;}

}

static void Main(string[] args){

// 委托的对象Call objCall;// Math 类的对象Math objMath = new Math();// 将方法与委托关联起来objCall = new Call(objMath.Multiply);// 将委托实例化result = objCall(5, 3);System.Console.WriteLine(" 结果为 {0}",

result);}

将方法与委托关联起来将方法与委托关联起来

Page 24: .NET 平台和 C# 编程

24

Information Engineering

Department of SCEMI事件

抢答者

宣布人

抢答者

“ 请听题 ~”

集中注意力聆听其他人

事件源

事件的发布者

事件的订阅人

未订阅该事件

• 定义事件• 为对象订阅该事件 • 将发生的事件通知给订阅人

Page 25: .NET 平台和 C# 编程

25

Information Engineering

Department of SCEMI 定义事件

[ 访问修饰符 ] event 委托名 事件名 ; [ 访问修饰符 ] event 委托名 事件名 ;

语法语法

public delegate void delegateMe();

private event delegateMe eventMe;

Page 26: .NET 平台和 C# 编程

26

Information Engineering

Department of SCEMI 订阅事件

eventMe += new delegateMe(objA.Method);

eventMe += new delegateMe(objB.Method);

Page 27: .NET 平台和 C# 编程

27

Information Engineering

Department of SCEMI 通知订阅对象

if(condition){

eventMe();

}调用订阅特定事件的对象的所有委托调用订阅特定事件的对象的所有委托

Page 28: .NET 平台和 C# 编程

28

Information Engineering

Department of SCEMI

演示:示例 4

示例class TestEvents{

[STAThread]static void Main(string[] args){ // 委托的对象 Delegate objDelegate = new Delegate(); // ClassA 的对象 ClassA objClassA = new ClassA(); // ClassB 的对象 ClassB objClassB = new ClassB(); // 订阅该事件 objDelegate.NotifyEveryOne += new Delegate.MeDelegate(objClassA.DispMethod); objDelegate.NotifyEveryOne += new Delegate.MeDelegate(objClassB.DispMethod);

objDelegate.Notify();}

}

class Delegate{

// 定义委托public delegate void MeDelegate();// 定义事件public event MeDelegate NotifyEveryOne;

public void Notify(){

// 如果事件不为 nullif(NotifyEveryOne != null){

Console.WriteLine(" 触发事件: ");// 触发事件NotifyEveryOne();

}}

}

class Delegate{

// 定义委托public delegate void MeDelegate();// 定义事件public event MeDelegate NotifyEveryOne;

public void Notify(){

// 如果事件不为 nullif(NotifyEveryOne != null){

Console.WriteLine(" 触发事件: ");// 触发事件NotifyEveryOne();

}}

}

class ClassA{

public void DispMethod(){

Console.WriteLine(“Class A 已接到 NotifyEveryOne 事件的通知! ");

}} // 第二个类class ClassB{

public void DispMethod(){

Console.WriteLine(“Class B 已接到 NotifyEveryOne 事件的通知! ");

}}

class ClassA{

public void DispMethod(){

Console.WriteLine(“Class A 已接到 NotifyEveryOne 事件的通知! ");

}} // 第二个类class ClassB{

public void DispMethod(){

Console.WriteLine(“Class B 已接到 NotifyEveryOne 事件的通知! ");

}}

0

Page 29: .NET 平台和 C# 编程

29

Information Engineering

Department of SCEMI 总结 属性通过使用访问器读取和写入类中的字段,对字段进行保护

属性分类为以下四种不同的类型: 读 / 写属性 只读属性 只写属性

可以在类中定义索引器,允许使用下标对该类的对象中的数据进行访问

索引器必须总是命名为 this ,因为对它们的访问是通过其所属的对象进行的

委托包含对方法而不是方法名称的引用 C# 中的事件允许一个对象将发生的事件或修改通知其他

对象