《国王与乞丐》班里聚餐麦霸唱的歌,很好听。闺蜜来北京,带她嗨了三天,该回归正常的上班生活了。为了可以跳到一个好的公司,继续复习我的C#。
一、抽象类:(abstract)
- 抽象就是从多个事物中将共性的,本质的内容抽取出来。
- C#中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
- 如果一个类中包括抽象方法,那该类也必须为抽象类。抽象类中可以有普通方法。
- 抽象类不能被实例化,因为抽象方法没有具体的实现。抽象类通过子类实例化。
- 子类实现父类的抽象方法需要用重写(override)实现,不能用new,而父类中的抽象方法不能加virtual。
- 权限修饰符不能为private、protected。
abstract class A {
public
abstract void fun();
}
class B :A
{
public
override void fun()
{
throw new NotImplementedException();
}
}
- 抽象类有构造函数,虽然抽象类不能够创建对象,但其子类要进行实例化,此时要调用父类无参构造。
- 抽象类不一定有抽象方法。
- 方法、属性、事件、索引可以用abstract修饰。数据成员(即成员变量)不可以用abstract修饰。
- 任何派生自抽象类的类必须使用override实现该类所有的抽象成员,除非该类也是抽象类。
- 抽象类与普通类:
a.相同点:
都是用来描述事物的,都在类的内部定义成员。
都可以被继承。
b.不同点:
普通类有足够的信息描述事物,而抽象类有时候会信息不全。
抽象类中可以有普通方法,而普通类中不可以有抽象方法。
抽象类一定是个父类,而普通类不一定是。
抽象类不能被实例化,而普通类可以被实例化。
二、接口(interface):避免了单继承的局限性。
- 当一个抽象类中没有普通函数的时候,可以使用接口来表示。
- 定义接口的时候,使用关键字interface,不用class 、abstract修饰。不可以使用private 、protected权限修饰符。接口名称以I开头。所以格式为:interface Ifun{},默认为public类型,可以写public。
- 接口里的成员可以是:方法、属性、索引、事件。不能是字段。
- 接口里的成员都有默认的修饰符:public 、abstract,所以格式为:返回类型 函数名();
- 当子类实现接口中的方法时,不用加override,因为子类本身就在重写。
- 接口与接口之间的关系为:继承,可以多继承;类和类之间的关系为:继承,只能单继承;类与接口之间的关系为:实现,可以多实现。
- 当一个类要继承一个类,并实现接口时,父类写在接口前边。
- 接口不能创建对象。
- 接口中的方法不能存在public、new、override、virtual、abstract。
- 当一个类实现多个接口,这些接口含有同样的方法时:
a.只实现一个方法,该方法用public 修饰。
b.如果要实现各个接口,或者方法返回类型不同,用接口名.方法()分别实现,不能用public 修饰。
- 接口与抽象类:
相同点:
接口和抽象类都是不断进行向上抽取而来的,不管是抽象类还是接口,都是用来表述事物特点的。
不同点:
抽象类需要被继承,而且只能单继承;接口需要被实现,可以多实现和多继承;
抽象类中可以定义抽象和非抽象方法,子类继承后可以直接使用非抽象方法,并且要实现所有抽象方法;接 口只能定义抽象方法,必须由抽象类全部实现。
抽象类的继承是is...a的关系(所属关系);而接口的实现是like...a的关系(相似关系);
interface I1
{
void Show();
}
interface I2
{
void Show();
}
interface I3:I1,I2
{
void Show3();
}
class C
{
public void fun() //5
{
}
}
class D : C, I3
{
public void Show() //1.只实现一个,用public修饰
{
}
void I1.Show() //2.不能加public 等权限修饰符
{
}
void I2.Show() //3.不能加public 等权限修饰符
{
}
public void Show3() //4.必须加public
{
}
public new void fun() //6
{
}
}
实例化:
static void Main(string[] args)
{
D d = new D();
if (d is I1)
{
d.Show(); //调用1
}
I1 i1 = d as I1;
i1.Show(); //2
((I2)d).Show(); //3
((I3)d).Show3(); //4
((C)d).fun(); //5
d.fun(); //6
}
as运算符用于执行两个引用类型之间的显示转换,它是一种安全的转换,使用前不需要用is运算符测试类型,在类型不兼容的时候,转换的结果是null,而不会抛出异常。