Chinaunix首页 | 论坛 | 博客
  • 博客访问: 128091
  • 博文数量: 22
  • 博客积分: 596
  • 博客等级: 二等列兵
  • 技术积分: 874
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-06 12:09
个人简介

Enjoy code,enjoy life!

文章分类
文章存档

2013年(11)

2012年(11)

分类: C#/.net

2013-04-18 16:52:17

1.类实现契约:
    很多时候,当设计一个应用或者系统的时候,需要描绘一个契约的概念.编程的契约和其他契约没什么不同,通常可以定义一个契约来方便设计中两个类型之间的通信.比如说,假设有一个虚拟的动物园,园中有动物.现在,一个ZooKeeper的实例需要一种手段来与这些ZooDweller对象的集合通信,告诉它们要飞到一个特定的位置.且不论他们是否都能绝对服从,它们最好首先都能会飞.然而,并不是所有的动物都会飞,所以很清楚,不是动物园中的所有的类型都能够支持这个飞的契约.
    让我们考虑一种方法来管理让这些动物从一处飞到下一处的复杂功能.首先,考虑在这里可以做的假设.假设这个Zoo只能有一个ZooKeeper.其次,假设可以使用一个简单的二维点结构来为Zoo内的位置建模.最初看起来好像可以用下面的代码为这个系统建模:

点击(此处)折叠或打开

  1. using System;
  2. using System.Collection.ObjectModel;

  3. namespace CityOfShanoo.MyZoo
  4. {
  5.   public struct Point
  6.   {
  7.     public double X;
  8.     public double Y;
  9.   }

  10.   public abstract class ZooDweller
  11.   {
  12.     public void EatSomeFood()
  13.     {
  14.       DoEatTheFood();
  15.     }
  16.     protected abstract void DoEatTheFood();
  17.   }

  18.   public sealed class ZooKeeper
  19.   {
  20.     public void SendFlyCommand(Point to)
  21.     {
  22.        //Implementation removed for clarity.

  23.     }
  24.   }

  25.   public sealed class Zoo
  26.   {
  27.     private static Zoo theInstance = new Zoo();
  28.     public static Zoo GetInstance()
  29.     {
  30.        return theInstance;
  31.     }
  32.     private Zoo()
  33.     {
  34.        creatures = new Collection<ZooDweller>();
  35.        zooKeeper = new ZooKeeper();
  36.     }
  37.     public ZooKeeper ZooKeeper
  38.     {
  39.        get
  40.        {
  41.          return zooKeeper;
  42.        }
  43.     }
  44.     private ZooKeeper zooKeeper;
  45.     private Collection<ZooDweller> creatures;
  46.   }
  47. }
        
    CityOfShanoo中可能只有一个zoo,这样,zoo就被设计为一个单件对象,而且获取这个唯一的zoo的实例的唯一方法就是调用Zoo.GetInstance.此外,也可以通过Zoo.ZooKeeper属性获得对ZooKeeper的引用,.NET框架中通常的做法是在这一属性所代表的自定义类型后面显示该属性的名称.
    初始的设计把ZooDweller定义为一个实现了EatSomeFood方法的抽象类.ZooDweller使用了NVI(Non-Virtual Interface, 非虚接口)模式,具体类型需要覆盖的虚方法声明为protected而不是public.
    有必要注意ZooDweller类型,实际上,它定义了契约,即使它不是一个接口.这个契约,规定了它从ZooDweller继承的任何类型必须实现EatSomeFood方法.任何使用ZooDweller实例的代码都被保证支持这个方法.

2.使用接口和类实现契约的规则:
(1) 如果需要创建一个"is-a"关系的模型,使用类:如果用名词来命名契约合适,那么可能需要用一个类来创建模型.
(2) 如果需要创建一个实现的关系,使用接口: 如果用形容词来命名契约合适,那么可能需要用一个接口来创建模型.
(3) 考虑将接口和抽象类的声明集中在一个独立的程序集中: 其他程序集中地实现可以引用这个独立的程序集.
(4) 如果可能,优先使用类而不是接口: 这将有助于增加扩展性.

3.重载操作符
    基本上有3中不同的可重载操作符:
(1) 一元操作符: 一元操作符只接受一个参数.常见的一元操作符包括++和--操作符.
(2) 二元操作符: 顾明思义,二元操作符接受两个参数,包括常见的算术操作符,如+、-、/、*以及我们熟悉的比较运算符.
(3) 转换操作符: 转换操作符定义用户自定义的转换.它们的操作数或者声明的返回值类型必须与包含它们的类或者结构类型相同.
    操作符重载,就是把已经定义的,有一定功能的操作符重新定义,来完成更为细致具体的运算等功能.操作符重载可以将概括性的抽象操作符具体化,便于外部调用而无需知晓内部具体运算过程.例如,通常需要编写类似于一下内容的代码,已将两个数字相加:

点击(此处)折叠或打开

  1. int a = 1;
  2. int sum = a + b;
    如果可以使用代表复数的用户定义的类型来编写相同类型的表达式,那当然是最好不过的了:

点击(此处)折叠或打开

  1. Complex a = 1;
  2. Complex sum = a + b;
    此代码可以很好地运行,但Complex类型并不能像语言中的预定义类型那样发挥作用.某种程度上操作符重载就是让struct、class、Interface等能够进行运算.
    实现C#操作符重载需先写关键词public和static,后跟返回类型,后跟operator关键词,后跟要声明的操作符符号,最后在对一对圆括号中添加适当的参数,如下所示:
    public static int operator+(int lhs, int rhs)
    {
   ...
   }
C#操作符重载方法:1.编写操作符重载方法; 2.实例化后,进行操作符运算.如果操作符是public的,所有操作符都必须是public的;如果操作符是static的,所有操作符都必须是static的,操作符不具有多态性.而且不能使用virtual/abstract/override或者sealed修饰符.二元操作符有两个显式参数,一元操作符有一个显式参数.

阅读(1683) | 评论(0) | 转发(0) |
1

上一篇:C#捷径编程笔记8

下一篇:GSM/GPRS开发笔记1

给主人留下些什么吧!~~