接口和抽象类的异同 相同点:都包含有可以由派生类继承的成员,他们都不能直接实例化,但可以声明它们的变量。如果这样做,就可以使用多态性把继承这两种类型的对象指定给它们的变量。接着通过这些变量来使用这些类型的成员,但不能访问派生类对象的其他成员。 相异点:①派生类只能有一个基类,即只能继承一个抽象类(但可以用一个继承链包含多个抽象类)。相反,类可以使用任意多个接口。②抽象类可以拥有抽象成员(没有代码体,且必须在派生类中实现,否则,派生类也是抽象类),也可以拥有非抽象成员(它们拥有代码体,也可以是虚拟的,这样就可以在派生类里重写)。另一方面,接口成员必须都在使用接口的类上执行,因为它们没有代码体③接口成员被定义为公共的(因为它们倾向于在外部使用),但抽象类的成员却可以是私有的(只要它们不是抽象的)、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。另外,接口不包含字段、构造函数、析构函数、静态成员和常量。
这说明这两种类型用于完全不相同目的,抽象类主要用作对象系列的基类,共享某些主要特性,例如共同的目的和结构。接口则主要有类来使用,其中这些类在基础水平上有所不同,但应可以完成某些相同的任务。
结构和类的异同 结构和类非常相似,但结构是值类型的,类是引用类型的
阴影复制和深度复制 阴影复制通过实现System.Object的受保护的MemberWiseClone()方法。 深度复制通过实现一个接口ICloneable,如果使用这个接口,就必须实现他包含的一个方法Clone。 类中成员的定义,包括字段、方法和属性,所有这些成员都有自己的访问级别: public 成员可以由任意代码访问。 private 成员只能由类中的代码访问(如果没有使用任何关键字,就默认此) protected 成员只能由类和派生类中的代码访问。 internal 成员只能由定义它的工程(程序集)内部的代码访问。 protected internal 它们只能由工程(程序集)中派生类的代码来访问 字段、方法和属性还都可以使用关键字static 来声明。表示是属于类的静态成员,不是对象实例的成员。 定义字段 关键字readonly, 表示这个字段只能在执行构造函数和初始化时赋值。可以使用const来创建一个常量。按照定义,Const成员也是静态的,所以不需要static 修饰。 定义方法 virtual 方法可以重写 abstract 方法必须重写(只用于抽象类中) override 方法重写了一个基类的方法(如果方法被重写,就必须使用此关键字) external 方法定义放在其他的地方。 override sealed 指定在派生类中不能对此方法进一步的修改。 定义属性 get, set ,value 关键字,value引入用户提供的属性值。 可以使用virtual, abstract, static关键字 调用重写或隐藏的基类方法 base关键字①指定.NET的实例化过程,以使用基类中匹配指定签名的构造函数。②也可以使用这个关键字指定基类构造函数的字面值。③它表示在派生类中基类的实现(控制构造函数时,用法类似)。Base 使用对象实例,所以在静态成员中使用它会产生错误。 接口的实现 接口成员的定义和类的定义相似,但有几个重要区别: ①不允许使用访问修饰符(public, private, protected, internal),所有成员接口都是公共的。 ②接口成员不能包含代码体。 ③接口不能定义字段成员④ ⑤接口成员不能用关键字static, virtual, abstract, sealed来定义。 ⑥类型定义成员是禁止的,但要隐藏继承了基接口的成员,可以用关键字new来定义它。 实现接口的类必须包含该接口所有成员的实现,且必须匹配指定的签名(包括匹配指定的get块set块),并且必须是公共的。可以使用关键字virtual, abstract来执行接口成员,但不能使用static, const. 接口成员还可以在基类上实现。
显式实现接口成员 下列运算符可以重载: 一元:+, -, !, ~,++, --,true, false 二元:+, -, *, /, %, &, |, ^, <<, >> 比较运算符:==, !=, <, >, <=, >=
封箱(boxing)和拆箱(unboxing)---引用类型和值类型之间的转换。 Is运算符―用于查看变量,看看它是否是给定的类型,或者是否和该类型兼容。 As运算符-用于把变量转换为指定的类型,这与数据转换略有不同。 |