C# 语言的高级应用


1、属性

例1:属性概念的引入(问题)

public class Animal
{public int Age;public double Weight;public bool Sex;public Animal(int age, double weight, bool sex){Age = age;Weight = weight;Sex = sex;}public void Eat(){Console.WriteLine("Animal Eat.");}public void Sleep(){Console.WriteLine("Animal Sleep.");}public override string ToString(){return string.Format("Animal Age:{0}, Weight:{1}, Sex:{2}", Age, Weight, Sex);}
}
class Program
{static void Main(string[] args){Animal al = new Animal(1, 1.2, false);Console.WriteLine("Animal Age:{0}, Weight:{1}, Sex:{2}", al.Age, al.Weight, al.Sex);al.Age = -1;al.Weight = -0.5;Console.WriteLine(al);}
}

例2:问题的解决(Java语言解决该问题的方案)

public class Animal
{private int _age;private double _weight;private readonly bool _sex;public int GetAge(){return _age;}public void SetAge(int value){_age = (value > 0) ? value : 0;}public double GetWeight(){return _weight;}public void SetWeight(double value){_weight = (value > 0) ? value : 0;}public bool GetSex(){return _sex;}public Animal(int age, double weight, bool sex){_age = (age > 0) ? age : 0;_weight = (weight > 0) ? weight : 0;_sex = sex;}public void Eat(){Console.WriteLine("Animal Eat.");}public void Sleep(){Console.WriteLine("Animal Sleep.");}public override string ToString(){return string.Format("Animal Age:{0}, Weight:{1}, Sex:{2}", _age, _weight, _sex);}
}
class Program
{static void Main(string[] args){Animal al = new Animal(1, 1.2, false);Console.WriteLine("Animal Age:{0},Weight:{1},Sex:{2}", al.GetAge(), al.GetWeight(), al.GetSex());al.SetAge(-1);al.SetWeight(-0.5);Console.WriteLine(al);}
}

例3:属性的提出

public class Animal
{private int _age;private double _weight;private readonly bool _sex;public int Age{get { return _age; }set { _age = (value > 0) ? value : 0; }}public double Weight{get { return _weight; }set { _weight = (value > 0) ? value : 0; }}public bool Sex{get { return _sex; }}public Animal(int age, double weight, bool sex){_age = (age > 0) ? age : 0;_weight = (weight > 0) ? weight : 0;_sex = sex;}public void Eat(){Console.WriteLine("Animal Eat.");}public void Sleep(){Console.WriteLine("Animal Sleep.");}public override string ToString(){return string.Format("Animal Age:{0}, Weight:{1}, Sex:{2}", Age, Weight, Sex);}
}
class Program
{static void Main(string[] args){Animal al = new Animal(1, 1.2, false);Console.WriteLine("Animal Age:{0}, Weight:{1}, Sex:{2}", al.Age, al.Weight, al.Sex);al.Age = -1;al.Weight = -0.5;Console.WriteLine(al);}
}

说明:C#在声明data时就可以定义setget方法。

  • get:定义读取操作。
  • set:定义赋值操作,value表示传入的参数值。

例4:属性的简化

public class Animal
{private int _age;private double _weight;public int Age{get { return _age; }set { _age = (value > 0) ? value : 0; }}public double Weight{get { return _weight; }set { _weight = (value > 0) ? value : 0; }}public bool Sex { get; private set; }public Animal(int age, double weight, bool sex){_age = (age > 0) ? age : 0;_weight = (weight > 0) ? weight : 0;Sex = sex;}public void Eat(){Console.WriteLine("Animal Eat.");}public void Sleep(){Console.WriteLine("Animal Sleep.");}public override string ToString(){return string.Format("Animal Age:{0},Weight:{1},Sex:{2}", Age, Weight, Sex);}
}
class Program
{static void Main(string[] args){Animal al = new Animal(1, 1.2, false);Console.WriteLine("Animal Age:{0}, Weight:{1}, Sex:{2}", al.Age, al.Weight, al.Sex);al.Age = -1;al.Weight = -0.5;Console.WriteLine(al);}
}

说明:属性可以看作是对私有数据部分增加的一层隔离。


2、索引器

2.1 定义

是集合类中的一种特殊属性,可使得集合类中的元素像数组元素一样访问。

2.2 语法结构

public 元素类型 this[int index]
{get { ... }set { ... }
}public 元素类型 this[string name]
{get { ... }set { ... }
}

例5:利用索引器实现对集合类StudentSet中元素Student的访问。

public class Student
{private string _name;public string Name{get { return _name; }set{_name = string.IsNullOrEmpty(value)? "NULL": value;}}public long ID { get; set; }public Student(long id, string name){ID = id;_name = name;}public override string ToString(){return string.Format("ID:{0},Name:{1}", ID, Name);}
}
public class StudentSet
{private readonly int _maxCount = 500;private readonly Student[] _stus;public int Count{get; private set;}public StudentSet(){Count = 0;_stus = new Student[_maxCount];}public void Add(Student stu){if (stu == null)throw new ArgumentNullException();if (Count == _maxCount)throw new IndexOutOfRangeException();_stus[Count] = stu;Count++;}public Student this[int index]{get{if (index < 0 || index > Count - 1)throw new IndexOutOfRangeException();return _stus[index];}set{if (index < 0 || index > Count - 1)throw new IndexOutOfRangeException();if (value == null)throw new ArgumentNullException();_stus[index] = value;}}
}
class Program
{static void Main(string[] args){StudentSet stuSet = new StudentSet();stuSet.Add(new Student(10086, "张三"));stuSet.Add(new Student(95988, "李四"));stuSet[1].Name = string.Empty;Console.WriteLine(stuSet.Count); Console.WriteLine(stuSet[0]); Console.WriteLine(stuSet[1]); Console.WriteLine(stuSet[2]);//未处理的异常:  System.IndexOutOfRangeException: 索引超出了数组界限。}
}

3、接口

3.1 概念

  • 接口是类设计的蓝图,即只提供声明而没有实现。
  • 接口不可以直接实例化对象(与抽象类相同)。
  • C#允许一个类实现多个接口(注意与继承的区别)。
  • 接口就是包含一系列不被实现的方法,而把这些方法的实现交给继承它的类。

3.2 表示

例6:根据类图利用Dog实现IAnimal接口

public interface IAnimal
{int Age { get; set; }double Weight { get; set; }void Eat();void Sleep();
}
public class Dog : IAnimal
{private int _age;private double _weight;public int Age{get { return _age; }set { _age = (value >= 0) ? value : 0; }}public double Weight{get { return _weight; }set { _weight = (value >= 0) ? value : 0; }}public void Eat(){Console.WriteLine("Dog Eat");}public void Sleep(){Console.WriteLine("Dog Sleep");}
}
class Program
{static void Main(string[] args){IAnimal al = new Dog();al.Age = 1;al.Weight = 2.5;Console.WriteLine("Dog:Age={0}, Weight={1}", al.Age, al.Weight);al.Eat();al.Sleep();}
}

例7:利用接口实现“饲养系统”

某饲养员(Raiser)在目前状态下需要饲养三种动物:狗(Dog)、鸟(Bird)和鱼(Fish),该三种动物只需要让其睡觉(Sleep)和吃饭(Eat)即可。请设计该饲养系统,要求满足软件设计的“开闭原则”。

方案一:(在抽象类部分已经给出)

方案二:

public interface IAnimal
{int Age { get; set; }double Weight { get; set; }void Eat();void Sleep();
}
public class Bird : IAnimal
{private int _age;private double _weight;public int Age{get { return _age; }set { _age = (value >= 0) ? value : 0; }}public double Weight{get { return _weight; }set { _weight = (value >= 0) ? value : 0; }}public void Eat(){Console.WriteLine("Bird Eat.");}public void Sleep(){Console.WriteLine("Bird Sleep.");}public void Fly(){Console.WriteLine("Bird Fly.");}
}
public class Dog : IAnimal
{private int _age;private double _weight;public int Age{get { return _age; }set { _age = (value >= 0) ? value : 0; }}public double Weight{get { return _weight; }set { _weight = (value >= 0) ? value : 0; }}public void Eat(){Console.WriteLine("Dog Eat.");}public void Sleep(){Console.WriteLine("Dog Sleep.");}public void Run(){Console.WriteLine("Dog Run.");}
}
public class Fish : IAnimal
{private int _age;private double _weight;public int Age{get { return _age; }set { _age = (value >= 0) ? value : 0; }}public double Weight{get { return _weight; }set { _weight = (value >= 0) ? value : 0; }}public void Eat(){Console.WriteLine("Fish Eat.");}public void Sleep(){Console.WriteLine("Fish Sleep.");}public void Swim(){Console.WriteLine("Fish Swim.");}
}
public class Raiser
{public void Raise(IAnimal al){al.Eat();al.Sleep();}
}
class Program
{static void Main(string[] args){Raiser rsr = new Raiser();rsr.Raise(new Dog());rsr.Raise(new Bird());rsr.Raise(new Fish());}
}

3.3 接口(interface)与抽象类(abstract class)

(1)相同点:

  • 接口与抽象类都不可以直接实例化对象。

(2)不同点:

  • 抽象类中的数据和操作必须有限制修饰符,而接口中的数据和操作不可以有限制修饰符。
  • 抽象类中可以有带实现体的方法(非abstract方法),而接口只能有方法的声明。
  • 抽象类在子类中通过override关键字覆写抽象方法,而接口被子类直接实现。

例8:一个类可以实现多个接口,但要注意多个接口中有重名方法的处理。

方式一:

public interface IHighWayWorker
{void HighWayOperation();void Build();
}
public interface IRailWayWorker
{void RailWayOperation();void Build();
}
public class Worker : IRailWayWorker, IHighWayWorker
{public void HighWayOperation(){Console.WriteLine("HighWayOperation.");}public void RailWayOperation(){Console.WriteLine("RailWayOperation");}public void Build(){Console.WriteLine("HighWay,RailWay,Build.");}
}
class Program
{static void Main(string[] args){Worker wr = new Worker();wr.Build(); // HighWay,RailWay,Build.IHighWayWorker hwr = new Worker();hwr.Build(); // HighWay,RailWay,Build.hwr.HighWayOperation(); // HighWayOperation.IRailWayWorker rwr = new Worker();rwr.Build(); // HighWay,RailWay,Build.rwr.RailWayOperation();// RailWayOperation}
}

方式二:

public interface IHighWayWorker
{void HighWayOperation();void Build();
}
public interface IRailWayWorker
{void RailWayOperation();void Build();
}
public class Worker : IHighWayWorker, IRailWayWorker
{public void HighWayOperation(){Console.WriteLine("HighWayOperation.");}public void RailWayOperation(){Console.WriteLine("RailWayOperation");}void IHighWayWorker.Build(){Console.WriteLine("HighWay Build.");}void IRailWayWorker.Build(){Console.WriteLine("RailWay Build.");}// 注意:void IHighWayWorker.Build()和void IRailWayWorker.Build()// 前面不能够加限制修饰符。
}
class Program
{static void Main(string[] args){Worker wr = new Worker();//wr.Build(); 该语句错误IHighWayWorker hwr = new Worker();hwr.Build();//HighWay Build.hwr.HighWayOperation();//HighWayOperation.IRailWayWorker rwr = new Worker();rwr.Build();//RailWay Build.rwr.RailWayOperation();//RailWayOperation}
}

4、泛型

例9:存储int数据类型的集合及操作。

public class IntSet
{private readonly int _maxSize;private readonly int[] _set;public IntSet(){_maxSize = 100;_set = new int[_maxSize];//...}public void Insert(int k, int x){//...._set[k] = x;}public int Locate(int k){//...return _set[k];}
}
class Program
{static void Main(string[] args){IntSet iSet = new IntSet();iSet.Insert(0, 123);int i = iSet.Locate(0);Console.WriteLine(i); // 123}
}

例10:存储string数据类型的集合及操作。

public class StringSet
{private readonly int _maxSize;private readonly string[] _set;public StringSet(){_maxSize = 100;_set = new string[_maxSize];//...}public void Insert(int k, string x){//...._set[k] = x;}public string Locate(int k){//...return _set[k];}
}
class Program
{static void Main(string[] args){StringSet strSet = new StringSet();strSet.Insert(0, "abc");string j = strSet.Locate(0);Console.WriteLine(j); // abc}
}

例11:利用object类存储通用数据类型的集合及操作。

public class GSet
{private readonly int maxSize;private readonly object[] _set;public GSet(){maxSize = 100;_set = new object[maxSize];//...}public void Insert(int k, object x){//...._set[k] = x;}public object Locate(int k){//...return _set[k];}
}
class Program
{static void Main(string[] args){GSet gSet1 = new GSet();gSet1.Insert(0, 123);int k1 = (int)gSet1.Locate(0);Console.WriteLine(k1); // 123GSet gSet2 = new GSet();gSet2.Insert(0, "abc");string k2 = (string)gSet2.Locate(0);Console.WriteLine(k2); // abcGSet gSet3 = new GSet();gSet3.Insert(0, 123);gSet3.Insert(1, "abc");//编译时可以通过,运行时出现异常。int k3 = (int)gSet3.Locate(1); //这样使用存在类型安全问题。Console.WriteLine(k3);// 未处理的异常:  System.InvalidCastException: 指定的转换无效。}
}

泛型定义:即参数化类型。

在编译时用一个具体类型代替该参数类型,可定义类型安全的类而不影响工作效率。

例12:利用泛型T存储通用数据类型的集合及操作。

public class GSet<T>
{private readonly int _maxSize;private readonly T[] _set;public GSet(){_maxSize = 100;_set = new T[_maxSize];//...}public void Insert(int k, T x){//...._set[k] = x;}public T Locate(int k){//...return _set[k];}
}
class Program
{static void Main(string[] args){GSet<int> gSet1 = new GSet<int>();gSet1.Insert(0, 123);int k1 = gSet1.Locate(0);Console.WriteLine(k1); // 123GSet<string> gSet2 = new GSet<string>();gSet2.Insert(0, "abc");string k2 = gSet2.Locate(0);Console.WriteLine(k2); // abc}
}

我们把T称为类型参数,当然我们也可以对T进行约束。

例13:为类型参数T增加约束,比如T只能是值类型。

public class GSet<T> where T : struct
{private readonly int _maxSize;private readonly T[] _set;public GSet(){_maxSize = 100;_set = new T[_maxSize];//...}public void Insert(int k, T x){//...._set[k] = x;}public T Locate(int k){//...return _set[k];}
}
class Program
{static void Main(string[] args){GSet<int> gSet1 = new GSet<int>();gSet1.Insert(0, 123);int k1 = gSet1.Locate(0);Console.WriteLine(k1); // 123// GSet<string> gSet2 = new GSet<string>(); // 编译错误// 错误 CS0453 类型“string”必须是不可以为 null 值的类型,// 才能用作泛型类型或方法“GSet < T >”中的参数“T” }
}

有关泛型约束可以查看以下图文:

  • 技术图文:C#语言中的泛型 I
  • 技术图文:C#语言中的泛型 II

5、类与类之间的关系

public class Oxygen
{//...
}
public class Water
{//...
}
public abstract class Animal
{public int Age;public double Weight;public abstract void Eat();public abstract void Sleep();public abstract void Breed();public abstract void Metabolism(Oxygen o2, Water water);
}

public class Bird : Animal
{public string Feather;public void Fly(){//...}public void Egg(){//...}public override void Eat(){//...}public override void Sleep(){//...}public override void Breed(){//...}public override void Metabolism(Oxygen o2, Water water){//...}
}
public class Penguin : Bird
{//...
}
public class Goose : Bird
{//...
}
public class Duck : Bird
{//...
}

public class Climate
{//...
}
public class Penguin : Bird
{private Climate _climate;//...
}

public interface ILanguage
{void Speak();
}
public class DonaldDuck : Duck, ILanguage
{public void Speak(){//...}//...
}

C# 语言的高级应用相关推荐

  1. C 语言编程 — 高级数据类型 — void 类型

    目录 文章目录 目录 前文列表 void 类型 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法> <C 语言编程 - 基本数据类型> & ...

  2. C 语言编程 — 高级数据类型 — 字符串

    目录 文章目录 目录 前文列表 字符串 字符串拷贝 字符串比较 strcmp strncmp 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法> &l ...

  3. C 语言编程 — 高级数据类型 — 共用体

    目录 文章目录 目录 前文列表 共用体 定义共用体 访问共用体成员 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法> <C 语言编程 - 基本 ...

  4. C 语言编程 — 高级数据类型 — 结构体与位域

    目录 文章目录 目录 前文列表 结构体 定义结构体 初始化结构体变量 访问结构体成员 结构体的内存分布 将结构体作为实参传入函数 指向结构体变量的指针 位域 定义位域 使用位域结构体的成员 前文列表 ...

  5. C 语言编程 — 高级数据类型 — 枚举

    目录 文章目录 目录 前文列表 声明枚举类型 定义枚举类型的变量 枚举类型变量的枚举值 枚举在 switch 语句中的使用 将整型转换为枚举类型 前文列表 <程序编译流程与 GCC 编译器> ...

  6. C 语言编程 — 高级数据类型 — 数组

    目录 文章目录 目录 前文列表 数组 声明数组 初始化数据 访问数组元素 二维数组 指向数组的指针 将数组指针作为实参传入函数 从函数返回一个数组指针 指针数组 数组名和取数组首地址的区别 前文列表 ...

  7. Linux基础和c语言的高级用法

    Linux基础 基础命令 与文件相关的: mkdir:创建一个目录文件 touch:创建一个普通文件 rmdir:删除一个空的目录文件 cd:+目录名:进入该目录文件 +路径:进入该路径下 ls:显示 ...

  8. c是高级程序语言吗,C语言是高级编程语言吗?

    C语言是高级编程语言吗? C语言是高级编程语言,高级语言主要是相对于汇编语言而言,基本脱离了机器的硬件系统,用于更易理解的方式编写程序,C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的 ...

  9. 合并多个结果集 SQL语言的高级用法

    GPS平台.网站建设.软件开发.系统运维,找森大网络科技! https://cnsendnet.taobao.com 来自森大科技官方博客 http://www.cnsendblog.com/inde ...

最新文章

  1. 一文运维zookeeper
  2. pythonweb开发-pythonWeb开发
  3. 请领导审阅并提意见应怎么说_职场中,领导不喜欢你,暗中排挤你,怎么办?老员工给你支5招!...
  4. Linux中如何打开trn文件,如何通过trn日志文件恢复SQL Server
  5. (67)SPI外设驱动接收驱动(六)(第14天)
  6. ie ajax异步缓存,IE下发送Ajax请求的缓存问题
  7. C++多线程编程(2) 条件变量与原子操作
  8. 16进制字符串转字节数组
  9. android 更新适配器,android – 当适配器数据更改时更新列表视图
  10. 用Not Exists 代替Not In
  11. 基于Tensorflow的MINIST手写体识别
  12. android音标,安卓系统如何正确显示音标
  13. js---如何通过js/jQuery代码出发节点的click事件
  14. 第十一章 枚举与泛型
  15. 抓取百度搜狗相关搜索、筛选文本相似度最高的相关搜索(PHP)
  16. 能转PDF格式用的在线软件
  17. 计算机相关装备有哪些,DNF装备搭配计算器_官方网站_17173DNF专区_17173.com中国游戏门户站...
  18. ValueError: List argument ‘indices‘ to ‘Sparse Concat‘ Op with length 0 shorter than minimum length2
  19. 男生除了干计算机软件还有什么职业,理想男朋友职业都有哪些?前10名竟然是……...
  20. 2018福大软工实践第十次作业

热门文章

  1. RNN训练方法介绍-BPTT
  2. 微信小程序模板功能1
  3. python实现加密解密功能(GUI)
  4. com.sun.javaws.Main.launchApp 无法加载制定文件jnlp文件
  5. HTTP Status Codes/HTTP状态码
  6. ICLR 2023 | GeneFace:高可泛化高保真度的说话人视频合成
  7. WordPress Gutenberg Block API:扩展块
  8. 单细胞基因可视化之UMAP图修饰
  9. GitHub学生认证,可以愉快的使用Copilot了
  10. 集成学习5-Xgboost原理与调参