450 likes | 562 Vues
第三章. 在 C# 中实现面向对象的概念. 目标. 理解 C# 的类和对象 使用 C# 构造函数和析构函数 使用 C# 访问修饰符 使用方法 理解命名空间. 对象. 属性. 行为. 型号. 行驶. 价格. 起动. 停车. 里程. 属性. 行为. 名称. 犬 吠. 颜色. 摇尾巴. 属性. 行为. 品种. 吃东西. 车轮数量. 刹车. 加速. 档的数量. 换档. 类. 类是 C# 中的一种结构,用于在程序中模拟现实生活的事物. 语法:. [ 访问修饰符 ] class < 类名 >. {
E N D
第三章 在C#中实现面向对象的概念
目标 • 理解 C#的类和对象 • 使用 C#构造函数和析构函数 • 使用 C#访问修饰符 • 使用方法 • 理解命名空间
对象 属性 行为 型号 行驶 价格 起动 停车 里程 属性 行为 名称 犬 吠 颜色 摇尾巴 属性 行为 品种 吃东西 车轮数量 刹车 加速 档的数量 换档
类 • 类是 C#中的一种结构,用于在程序中模拟现实生活的事物 语法: [访问修饰符] class <类名> { // 类的主体 } 示例: class Student { // 类的主体 } // 成员变量 // 成员方法
成员变量 语法: … class Student { private string _name; private char _gender; private string _class; private uint _grade; } … 数据类型 [访问修饰符] 成员变量; private int _name protected char status …. internal …. public bool userName 访问成员变量 步骤 1:创建一个类的对象 Student obj = new Student(); 步骤 2:使用点号访问成员变量 obj._name = “张三"; obj._name = 'M';
访问修饰符 2-1 Student 类 Teacher 类 private成员 不可访问 protected 成员 不可访问 public 成员 可以访问 只有 Student 类在 Teacher 类都在同一程序集中,才可访问internal成员 internal成员
构造函数 2-1 • 构造函数是类的一种特殊方法,每次创建类的实例都会调用它 语法: [访问修饰符] <类名>() { // 构造函数的主体 } 示例: … // 默认构造函数 Student() { _class = “信管"; } …
构造函数 2-2 class Student { private string _name; private char _gender; private string _class; private uint _grade; // 默认构造函数 private Student() { _class = “信管"; } static void Main(string[] args) { // 调用默认构造函数 Student obj = new Student(); Console.WriteLine(“班级= " + obj._class); Console.WriteLine(“成绩= " + obj._grade); } } 演示:示例 1
参数化构造函数 2-1 语法: [访问修饰符] <类名> ([参数列表]) { // 构造函数的主体 } 示例: … // 参数化构造函数 Student(string strclass) { _class = strclass; } …
参数化构造函数 2-2 public static void Main(string[] args) { // 调用默认构造函数 Student obj = new Student(); // 调用参数化构造函数 Student obj1 = new Student(“信管08“, ”张亮亮“, ‘男', 98); Console.WriteLine(“默认构造函数输出: \n班级=“ + obj._class); Console.WriteLine(“\n参数化构造函数输出: \n班级= " +obj1._class); } // 默认构造函数 private Student() { _class = “信管"; } // 参数化构造函数 private Employee(string strclass, string strName, char gender, uint grade) { _class = strclass; _name = strName; _gender = gender; _grade = grade; }
析构函数 • 是用于执行清除操作的特殊方法 语法: ~ <类名>()0 { // 析构函数的主体 } 示例: … ~ Student() { } …
方法 对象的行为 PickUp() { …. //用于传送和接收信号的代码 } Ring() { …. //用于显示主叫号码的代码 } 接听 响铃 挂断 Hang() { …. //用于结束会话的代码 }
声明方法 2-1 语法 [访问修饰符] 返回类型 <方法名>([参数列表]) { // 方法主体 } 访问修饰符(可选),默认情况下为private 如果不需要返回任何值,方法可能返回 void数据类型
声明方法 2-2 ….. class Point { int x; int y; void Assign() { System.Console.WriteLine(“输入点的x和y坐标"); x = int.Parse(System.Console.ReadLine()); y = int.Parse(System.Console.ReadLine()); } } ….. 方法 Assign()的定义 Assign( ) 方法 • 不返回任何值 (void) • 不接收任何值 (Assign())
调用方法 3-1 语法 对象名.方法名([参数列表]); 实例 点号 类中的方法
private void Create() { Console.WriteLine(“请输入实部:"); _real = int.Parse(Console.ReadLine()); Console.WriteLine(“请输入虚部:"); _imaginary = int.Parse(Console.ReadLine()); } void PrintResult() { Console.WriteLine(“两复数相加之和为:"); Console.WriteLine(_real + "+" + _imaginary + "i"); } // 此方法用于将两个复数相加 ComplexNumber ComplexAdd(ComplexNumber Param1) { Param1._real += _real ; Param1._imaginary += _imaginary; return Param1; } 调用方法 3-2 [STAThread] public static void Main(string[] args) { ComplexNumber Number1 = new ComplexNumber(); ComplexNumber Number2 = new ComplexNumber(); Number1.Create(); Number2.Create(); ComplexNumber Temp = Number1.ComplexAdd(Number2); Temp.PrintResult(); } 接收实部和虚部的值 显示实部和虚部的值 Param1与Number2相关联 演示:示例 3 请参阅对象的实例变量
调用方法 3-3 return语句 语法 return [表达式];
消费者1 方法重载 4-1 电话 电 管理层 帐单 电信 固定电话 电费 对不同的数据执行相同的任务 移动电话 供应商 1 电 供应商 2
方法重载 4-2 … Class Payment { … void PayBill(int telephoneNumber) { //此方法用于支付固定电话话费 } void PayBill(long consumerNumber) { //此方法用于支付电费 } void PayBill(long consumerNumber, double amount) { //此方法用于支付移动电话话费 } … } … 对不同数据执行相似的功能
方法重载4-3 int smallest(int num1, int num2) { Console.WriteLine(“{0} 和{1} 相比, 最小的是: ", num1, num2); if(num1 < num2) { return num1; } else { return num2; } } int smallest(int num1, int num2, int num3) { Console.WriteLine(“{0}, {1} 和 {2} 相比, 最小的是: ", num1, num2, num3); if(num1 < num2 && num1 < num3) { return num1; } else if(num2 < num1 && num2 < num3) { return num2; } else { return num3; } } 具有不同数量的参数的方法重载
方法重载 4-4 int smallest(int[] numbers) { int min = numbers[0]; for(int i = 1;i < numbers.Length;i++) { if(min > numbers[i]) min = numbers[i]; } return min; } double smallest(double[] numbers) { double min = numbers[0]; for(int i = 1;i < numbers.Length;i++) { if(min > numbers[i]) min = numbers[i]; } return min; } 具有不同类型的参数的方法重载
属性简介 3-1 class Student { private static string _name; //姓名 private static string _id; //学生id static void Main(string[] args) { _name = Console.ReadLine(); _id = Console.ReadLine(); } } • 直接访问字段 • 不经验证
属性简介 3-2 • … • Student s; • s.SetId("A1"); • string StudentId= s.GetId() • … class Student { 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 Student { 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 Account { private int _accountNo; //帐号 private double _balance; //余额 private double _interest; //利息 private static double _interestRate; // 利率是静态的,因为所有帐户获得的利息相同 // 构造函数初始化类成员 public Account(int No, double bal) { this._accountNo = No; this._balance= bal; } // 只读 AccountNumber属性 public int AccountNumber { get { return _accountNo; } } 只读属性 演示……
定义和调用属性 4-2 static void Main(string[] args) { // 创建 Account的对象 Account objAccount = new Account(5000, 2500); Console.WriteLine("输入到现在为止已获得的利息和利率"); objAccount. InterestEarned = Int64.Parse(Console.ReadLine()); Account.InterestRate = Int64.Parse(Console.ReadLine()); objAccount.InterestEarned += objAccount.Balance * Account.InterestRate; Console.WriteLine("获得的总利息为: {0}", objAccount.InterestEarned); } public double InterestEarned { get { return _interest; } set { // 验证数据 if (value < 0.0) { Console.WriteLine(“利息不能为负数"); return; } _interest = value; } } 将设置 InterestEarned属性
定义和调用属性 4-3 public static double InterestRate { get { return _interestRate; } set { // 验证数据 if (value < 0.0) { Console.WriteLine(“利率不能为负数"); return; } else { _interestRate = value / 100; } } static void Main(string[] args) { // 创建 Account 的对象 Account objAccount =new Account(5000, 2500);; Console.WriteLine("输入到现在为止已获得的利息和利率"); objAccount.InterestEarned = Int64.Parse(Console.ReadLine()); Account.InterestRate = Int64.Parse(Console.ReadLine()); objAccount.InterestEarned += objAccount.Balance * Account.InterestRate; Console.WriteLine("获得的总利息为: {0}", objAccount.InterestEarned); } 将设置 InterestRate属性
定义和调用属性 4-4 static void Main(string[] args) { // 创建 Account 的对象 Account objAccount = new Account(5000, 2500); Console.WriteLine(“输入到现在为止已获得的利息和利率"); objAccount.InterestEarned = Int64.Parse(Console.ReadLine()); Account.InterestRate = Int64.Parse(Console.ReadLine()); objAccount.InterestEarned += objAccount.Balance * Account.InterestRate; Console.WriteLine("获得的总利息为: {0}", objAccount.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]; } 演示……
public 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; } } 定义和调用索引器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 family = new Album(3); // 创建 3 张照片 Photo first = new Photo(" Jeny"); Photo second = new Photo("Smith"); Photo third = new Photo(“Lono"); // 向相册加载照片 family[0] = first; family[1] = second; family[2] = third; // 按索引检索 Photo objPhoto1 = family[2]; Console.WriteLine(objPhoto1.Title); // 按名称检索 Photo objPhoto2 = family[“Jeny"]; Console.WriteLine(objPhoto2.Title); }
命名空间 6-1 英国 纽卡斯尔 澳大利亚 纽卡斯尔
命名空间 6-2 类库 命名空间 AdminDept 命名空间 ITDept Class Manager { long int salary; ……… ……… } ……. ……. { long int salary; ……. ……… } Class Manager ITDept.Manager AdminDept.Manager
命名空间 6-3 namespace Sony { classTelevision { ... } classWalkMan { ... } } namespacePhilips { classTelevision { ... } classWalkMan { ... } } Class SonyTelevision { } Class PhilipsTelevision { } 长名称难以维护 Class PhilipsWalkman { } Class SonyWalkman { } 有条理,有结构 Sony.Television Philips.Television
命名空间 6-4 语法 namespace命名空间的名称 { // 该名称空间的所有类都放在这里。 }
命名空间 6-5 namespace Philips { class Monitor { public void ListModels() { Console.WriteLine(“供应以下型号的显示器:"); Console.WriteLine("15\", 17\" \n"); } [STAThread] static void Main(string[] args) { // // TODO: 在此处添加代码以启动应用程序 // } } }
namespace Sony { public class Monitor { public void ListModelStocks() { Console.WriteLine(“以下是 Sony 显示器的规格及其库存量:"); Console.WriteLine(“15\"=500, 17\"=2000, 19\"=3000"); } static void Main(string[] args) { Philips.Monitor objPhilips = new Philips.Monitor(); Monitor objSony = new Monitor(); objPhilips.ListModels(); objSony.ListModelStocks(); } } } 命名空间 6-6
总结 • 类是 C#中的一种结构,用于在程序中模拟现实生活的对象 • 成员变量表示对象的特征 • 方法表示对象可执行的操作 • 如果类中未定义构造函数,则由运行库提供默认构造函数 • 析构函数不能重载,并且每个类只能有一个析构函数 • 可以根据不同数量的参数或不同数据类型参数对方法进行重载,不能根据返回值进行方法重载 • 命名空间用来界定类所属的范围,类似于Java中的包