第六章 属性、索引器、委托和事件.

Slides:



Advertisements
Similar presentations
软件编程基础 一、程序的编辑 Java 源程序是以 Java 为后缀的简单的文本文件,可以用各种 Java 集成开发环境中的源代码编辑器来编写,也可以用其他文 本编辑工具,如 Windows 中的记事本或 DOS 中的 EDIT 软件等。 利用文字编辑器编写下列程序 public class Hello.
Advertisements

第 12 章 命 名 空 间 (时间: 1 次课, 2 学时)
单元二:面向对象程序设计 任务二:借书卡程序设计.
第三讲 面向对象(上).
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
JAVA 编 程 技 术 主编 贾振华 2010年1月.
项目7 面向对象高级.
项目6 通用堆栈.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
四資二甲 第三週作業 物件導向程式設計.
C#程序设计案例教程 第3章 程 序 结 构.
面向对象的程序设计(一).
第一章 面向对象程序设计.
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
C#程序设计 10软件1、2班 王槐彬 计算机工程学院.
類別與物件 Class & Object.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
程式設計實作.
第5章 异常处理 王德俊 上海交通大学继续教育学院.
C#程序设计 c# programming 泛型 C#程序设计课程组.
第八章 C#高级编程.
.NET 程式設計入門(使用 C#) 講師:鄧智鴻.
第二章 C# 基础知识.
第四章 在 C# 中实现 OOP 概念.
程序與函數的類別方法 目的:模組化程式設計 方法:由上而下設計 注意事項:(1)獨立性 (2)結合問題 (3)子問題間的溝通.
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
C#程序设计 c# programming 多线程 C#程序设计课程组.
第三章 C#面向对象初级编程 面向对象得程序设计越来越受到编程人员的喜爱。类和对象是面向对象程序设计中的重要概念。封装性、继承性和多态性是面向对象的特点,本章旨在全面说明C#编写面向对象程序设计的方法。
程式設計實作.
C++ with Managed Extensions
C#程序设计基础 $3 成员、变量和常量.
第9章 多线程 王德俊 上海交通大学继续教育学院.
第三章 在C#中实现面向对象的概念.
Java程序设计 第9章 继承和多态.
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
C#面向对象程序设计 $7 继承和多态性.
第6章 继承和接口设计 6.1 继 承 6.2 多态性 6.3 抽象类 6.4 接口 6.5 接口在集合排序中的应用.
并发机制 结果应该为: 线程 1: 1 线程 1: 2 线程 1: 3 线程 1: 4 线程 1: 5 线程 2: 6 线程 2: 7
第一次课后作业 1. C/C++/Java 哪些值不是头等程序对象 2. C/C++/Java 哪些机制采用的是动态束定
例外處理與 物件序列化(Exception Handling and Serialization of Objects)
第9讲 Java的继承与多态(一) 类的继承 子类的创建 方法覆盖.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
异常及处理.
Ch02-基礎語法.
C/C++/Java 哪些值不是头等程序对象
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
類別與物件 I (Classes and Objects I)
* 單元:電腦與問題解決 主題:Java物件導向程式設計-類別與物件 台南縣國立善化高中 蕭嘉民 老師
第三章 C# 基础知识.
第7章 繼承/多型/介面 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
辅导课程八.
第二章 Java基本语法 讲师:复凡.
第五章 介面/集合/泛型 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
C#程序设计基础 $3 成员、变量和常量.
第二章 Java基本语法 讲师:复凡.
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
第四章 类 4.1 基础知识 4.2 构造函数 4.3 方法 4.4 属性与索引 4.5 String类
第二章 Java基本语法 讲师:复凡.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
龍老師我不會Debug QQ.
方法進階及物件導向基礎 Lecturer: 楊昌樺.
第6單元 6-1 類別的繼承 (Class Inheritance) 6-2 抽象類別 (Abstract Class)
JAVA 程式設計與資料結構 第三章 物件的設計.
對於成員(member)存取權的限制 成員的資料被毫無限制的存取,任誰都可以指定任意值給成員,Java語言為了防止這種現象的產生,規定:有一種成員的資料不能任由類別外部的任何人隨意存取。
判斷(選擇性敘述) if if else else if 條件運算子.
輸出執行結果到螢幕上 如果要將執行結果的文字和數值都「輸出」到電腦螢幕時,程式要怎麼寫? class 類別名稱 {
第二章 Java基本语法 讲师:复凡.
第6章 继承和多态 伍孝金
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
Summary
Presentation transcript:

第六章 属性、索引器、委托和事件

回顾 继承是获得现有类的功能的过程 创建新类所根据的基础类称为基类或父类,新建的类则称为派生类或子类 base 关键字用于从派生类中访问基类成员 override 关键字用于修改方法、属性或索引器。new 访问修饰符用于显式隐藏继承自基类的成员 抽象类是指至少包含一个抽象成员(尚未实现的方法)的类。抽象类不能实例化 重写方法就是修改基类中方法的实现。virtual 关键字用于修改方法的声明 显式接口实现是用于在名称不明确的情况下确定成员函数实现的是哪一个接口

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

属性简介 3-1 class Employee { private static string _name; private static string _id; static void Main(string[] args) _name = Console.ReadLine(); _id = Console.ReadLine(); } 直接访问字段 不经验证

属性简介 3-2 属性 … Employee emp; emp.SetId("A1"); class Employee string Department = emp.Get() class Employee { private static string _name; private static string _id; public void SetId(value) // 验证输入长度小于 2 if (_id.Length > 2) _id = value; } public string GetId() return _id; 每次都调用 GetId() 和 SetId() 方法会很繁琐 属性 方法 SetId(Value) 和 GetId() 分别读取和写入职员 ID

属性简介 3-3 class Employee { private static string _name; private static string _id; public string Id get return _id; } set // 验证输入长度小于 2 if (_id.Length > 2) _id = value; 读取 ID 时调用 将值赋给 ID 时调用

属性类型 4-1 读/写属性 [访问修饰符] 数据类型 属性名 { get{ }; set{ }; } 可以赋值和检索值

属性类型 4-2 只读属性 [访问修饰符] 数据类型 属性名 { get{ }; } 只能检索值

属性类型 4-3 只写属性 [访问修饰符] 数据类型 属性名 { set{ }; } 只能赋值

属性类型 4-4 应用于整个类而不是类的实例 静态属性 [访问修饰符]static 数据类型 属性名 { get{}; set{}; } 只能访问类的静态成员 应用于整个类而不是类的实例

定义和调用属性 4-1 演示…… 只读属性 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-2 将设置 InterestEarned 属性 static void Main(string[] args) { // 创建 SavingsAccount 的对象 SavingsAccount objSavingsAccount = new SavingsAccount(12345, 5000);; Console.WriteLine("输入到现在为止已获得的利息和利率"); objSavingsAccount.InterestEarned = Int64.Parse(Console.ReadLine()); SavingsAccount.InterestRate = 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 属性

定义和调用属性 4-3 将设置 InterestRate 属性 static void Main(string[] args) { // 创建 SavingsAccount 的对象 SavingsAccount objSavingsAccount = new SavingsAccount(12345, 5000);; Console.WriteLine("输入到现在为止已获得的利息和利率"); objSavingsAccount.InterestEarned = Int64.Parse(Console.ReadLine()); SavingsAccount.InterestRate = objSavingsAccount.InterestEarned += objSavingsAccount.Balance * SavingsAccount.InterestRate; Console.WriteLine("获得的总利息为: {0}", objSavingsAccount.InterestEarned); } public static double InterestRate { get return _interestRate; } set // 验证数据 if (value < 0.0) Console.WriteLine(“利率不能为负数"); return; else _interestRate = value / 100; 将设置 InterestRate 属性

将检索 Balance 和 InterestRate 属性 定义和调用属性 4-4 static void Main(string[] args) { // 创建 SavingsAccount 的对象 SavingsAccount objSavingsAccount = new SavingsAccount(12345, 5000);; Console.WriteLine(“输入到现在为止已获得的利息和利率"); objSavingsAccount.InterestEarned = Int64.Parse(Console.ReadLine()); SavingsAccount.InterestRate = objSavingsAccount.InterestEarned += objSavingsAccount.Balance * SavingsAccount.InterestRate; Console.WriteLine("获得的总利息为: {0}", objSavingsAccount.InterestEarned); } public double Balance { get if (_balance < 0) Console.WriteLine("没有可用余额"); return _balance; } 将检索 Balance 和 InterestRate 属性

索引器 语法 [访问修饰符] 数据类型 this[数据类型 标识符] { get{}; set{}; }

定义和调用索引器 4-1 演示…… 以 Title 属性表示照片 将照片存放于数组 photos 中 class Photo { string _title; public Photo(string title) this._title = title; } public string Title get return _title; class Album { // 该数组用于存放照片 Photo[] photos; public Album(int capacity) photos = new Photo[capacity]; } 演示……

定义和调用索引器 4-2 带有 int 参数的 Photo 索引器 读/写索引器 public Photo this[int index] { get // 验证索引范围 if (index < 0 || index >= photos.Length) Console.WriteLine("索引无效"); // 使用 null 指示失败 return null; } // 对于有效索引,返回请求的照片 return photos[index]; set return; photos[index] = value; 定义和调用索引器 4-2 带有 int 参数的 Photo 索引器 读/写索引器

定义和调用索引器 4-3 带有 string 参数的 Photo 索引器 只读索引器 public Photo this[string title] { get // 遍历数组中的所有照片 foreach (Photo p in photos) // 将照片中的标题与索引器参数进行比较 if (p.Title == title) return p; } Console.WriteLine("未找到"); // 使用 null 指示失败 return null; 只读索引器

定义和调用索引器 4-4 static 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); }

委托 委托和方法必须具有相同的签名 在运行时确定调用哪种方法 Multiply(int,int) { …. } --- Divide(int,int) --- public delegate Call(int num1, int num2); 委托和方法必须具有相同的签名

[访问修饰符] delegate 返回类型 委托名(); 定义委托 2-1 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); 语法 [访问修饰符] delegate 返回类型 委托名(); 将方法与委托关联起来

定义委托 2-2 将方法与委托关联起来 class 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; 定义委托 2-2 将方法与委托关联起来 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); }

事件 不关心 事件的发布者 “请听题~” 其他人 抢答者 抢答者 事件源 定义事件 宣布人 为对象订阅该事件 将发生的事件通知给订阅人 集中注意力聆听 未订阅该事件 其他人 抢答者 抢答者 事件的订阅人

定义事件 public delegate void delegateMe(); 语法 [访问修饰符] event 委托名 事件名; public delegate void delegateMe(); private event delegateMe eventMe;

订阅事件 eventMe += new delegateMe(objA.Method); eventMe += new delegateMe(objB.Method);

通知订阅对象 if(condition) { eventMe(); } 调用订阅特定事件的对象的所有委托

示例 演示:示例 4 class ClassA class Delegate class TestEvents { { { // 定义委托 public void DispMethod() Console.WriteLine(“Class A 已接到 NotifyEveryOne 事件的通知!"); } // 第二个类 class ClassB Console.WriteLine(“Class B 已接到 NotifyEveryOne 事件的通知! "); class Delegate { // 定义委托 public delegate void MeDelegate(); // 定义事件 public event MeDelegate NotifyEveryOne; public void Notify() // 如果事件不为 null if(NotifyEveryOne != null) Console.WriteLine("触发事件:"); // 触发事件 NotifyEveryOne(); } 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); new Delegate.MeDelegate(objClassB.DispMethod); objDelegate.Notify(); } 演示:示例 4

总结 属性通过使用访问器读取和写入类中的字段,对字段进行保护 属性分类为以下四种不同的类型: 读/写属性 只读属性 只写属性 可以在类中定义索引器,允许使用下标对该类的对象中的数据进行访问 索引器必须总是命名为 this,因为对它们的访问是通过其所属的对象进行的 委托包含对方法而不是方法名称的引用 C# 中的事件允许一个对象将发生的事件或修改通知其他对象