二十、多态的实现:同一种操作,多种不同的响应。
1. 声明父类变量,实例化子类对象
2. 父类创建虚方法virtual,子类做重写override。---子类重写父类的方法
3. 虚方法提供了默认的实现,子类可以不重写,如果子类没有重写,那么就默认调用父提供的方法。如果子类重写了,系统会自动判断子类类型,调用子类的重写方法 -----这就是多态
4. 多态的核心在于:子类可以替换父类,原因:
a) 子类拥有父类所规范的所有属性和方法
b) 子类还可以拥有自己特定的属性和方法
c) 父类对象可以完成的功能子类对象都可以完成
d) 所以,子类可以替换父类。如Person per=new Student();
e) Per本质是一个子类对象,但是编译器不知道,所以per只能调用父类里面规范的成员。如果做强制转换,则可以调用到子类成员。
5. 如果需要系统自动判断类型,达到多态的目的需要做以下事情:
a) 实现继承---- 子类是父类
b) 父类中声明虚方法(抽象方法),子类做重写(override)
c) 声明父类变量,实例化子类对象 / 父类做为参数,传入子类对象。
6. 多态实现了避免反复的判断才能达到的效果,这也是多态的好处。
7. 抽象方法:abstract:只是方法的声明,没有方法体,但是必须包含 ;
8. 抽象方法的特点 :
a) 只有声明
b) 它必须在抽象类里面(抽象类里面不仅仅只包含抽象方法)
c) 所有子类必须重写父类的抽象方法,除非子类它也是抽象的,抽象类里面可以包含未实现的抽象方法 。
d) 抽象方法更多是一种规范,它规范了子类的行为。
e) 抽象类不能实例化。
9、多态的使用方式:
1.声明父类变量,实例化子类对象 ---创建父类类型集合
2.以父类做为方法的返回值,返回子类对象---简单工厂:用户需要频繁的得到不同的单个子类对象的时候
3.以父类类型做为参数,传入子类对象
10.如果父子类的方法参数不一样,那它是重载而不是重写。
二十一、简单工厂:制作产品:根据用户的需要,每一次制作出一个产品
1 public static Operator CreateOperator(string type) 2 3 { 4 5 Operator opt = null; 6 7 if (type == "+") 8 9 { 10 11 opt = new OpAdd(); 12 13 } 14 15 if (type == "-") 16 17 { 18 19 opt = new SubStract(); 20 21 } 22 23 if (type == "*") 24 25 { 26 27 opt = new Multi(); 28 29 } 30 31 if (type == "/") 32 33 { 34 35 opt = new Div(); 36 37 } 38 39 return opt; 40 41 }
二十二、is/as
1. is用来判断引用类型变量的变量是否是某一种类型
2. as:来做强制转换,一般()转换,如果不成功,就会报异常,as如果转换不成功会返回NULL,以后,如果不想抛出异常,可以使用as
二十三、软件设计中的几个原则:
1. 封装变化点
2. 开放封闭原则(对修改封闭,对扩展开放)---添加单独的功能—添加单独的方法; 添加单独的角色---添加单独的类
3. 高内聚,低藕合 ---三层---EF MVC
二十四、接口:
1. 接口本质就是一个抽象类,在接口里面就是声明一系列的属性,方法,索引器和事件。
2. 创建一个接口对象,其实就是创建一个 实现了这个接口的类 的对象
3. 如果某个类没有实现某个接口,那么这个这个类的对象不能强制转换为接口类型。
4. 接口不要求实现接口的类有某种关联,也就是说不要求他们要父子继承关系,方便了用户的拓展。
5. 在公司里面,接口更多的认为是一种规范。
6. 使用接口的方式:
a) 声明接口类型的变量,存入 实现了接口的类的 对象
b) 以接口类型做为参数,传入 实现了接口的类的 对象
7. 显示调用接口:显示实现接口的方法需要接口类型的对象才能调用。因类它默认是私有的,而且还不能人为修改为public
a) 如果声明的类型就是接口类型,那么可直接调用
b) 如果声明的类型是实现了接口的类的类型,那么就需要做强制转换。
8. 接口解决了通过继承实现多态的三个问题:
a) 通过继承实现多态只能是单继承,但是接口可以多实现
b) 通过继承实现多态的类必能够提取出共同的父类,也就说明这些类之间需要有共同的特征和行为。但是接口只需要它们有共同的行为。
c) 通过实现了继承的类做为参数传递,会传递类的对象的所有属性和方法,但是通过接口做为参数,只能调用到接口中声明的方法和属性。
二十五、结构
1, 结构是值 类继承自ValueType型
2, 它的使用方式和类很相似,但是也有一些区别:
a) 结构中不能为字段赋值
b) 结构不能包含显式的无参数构造函数
c) 如果通过构造函数为结构成员赋值,只能赋值给字段。
d) 如果不使用new来创建结构,那么就必须为结构中的字段赋值。
e) 结构是一个值类型,所以在做为参数传递的时候传递是值的副本,与引用类型不一致
f) 值类型做参数传递的时候会开辟新的空间来存储值,同时在同引用类型做转换的时候 需要 装箱和拆箱操作,消耗系统资源。
二十六、析构函数:
1. 每个类只能有一个,不能显示调用
2. 不能有访问修饰符,是系统自动调用的
3. ~Student()
{
Console.WriteLine("我调用了析构函数");
}