1.里氏转换
1.子类可以赋值给父类
2.如果父类中装的是子类对象,那么可以将这个父类强转为子类对象
注:子类对象可以调用父类中的成员,但是父类对象永远只能调用自己的成员
2.多态
/*
* 概念:让一个对象能够表现出多种的状态(类型)
* 使用多态可以最大化屏蔽对象之间的差异
* 实现多态的三种手段:1、虚方法 2、抽象类 3、接口
* 1)虚方法:
* a.将父类的方法标记为虚方法,使用关键字virtual,这个函数就可被子类重写 (需要找出一个父类)
* b.在子类的同名函数前加override表示重写该函数
* 虚方法:virtual override在子类方法中表示重写当前成员,使用虚方法后,如果父类中装的是子类对象,则父类可以调用子类重写的方法
* 父类中存在虚方法,则子类方法可以选择重写,也可以选择不重写
*
* ------具体会调哪个子类的函数,还得取决于父类中装的是哪个子类对象
* (知识点忘记:创建构造函数,创建对象的时候可以直接进行对象的初始化---给属性一一赋值)
*
*
*
* 2)抽象类: abstract 在子类继承的父类后Alt+Shift+F10快速重写 (需要提供抽象的成员)
* 当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法。(抽象方法是没有方法体的)(没大括号就叫做没有方法体)
* a.抽象类和接口不允许创建对象
* 1、抽象成员必须标记为abstract,并且不能有任何实现。抽象类中既可以有抽象成员,也可以有非抽象成员
* 2、抽象成员必须在抽象类中
* 3、抽象类不能被实例化
* 4、子类继承抽象类后,必须把父类中的所有抽象成员都重写(除非子类也是一个抽象类,则可以不重写)
* 5、抽象成员的访问修饰符不能是private
* 6、在抽象类中可以包含实例成员(并且抽象类的实例成员可以不被子类实现)
* 7、抽象类是有构造函数的。虽然不能被实例化
* 8、如果父类的抽象方法中有参数,那么,继承这个抽象父类的子类在重写父类的方法的时候也必须传入对应的参数
* 如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候,也必须要传入返回值。
* ===================================================================
* 如果父类中的方法有默认的实现,并且父类需要被实例化,这是可以考虑将父类定义成一个普通类,用虚方法来实现多态。
* 如果父类中的方法没有默认的实现,父类也不需要被实例化,则可以将该类定义为抽象类。
*
*
*
*
* 重写与隐藏的区别:
* 重写:提供同一个方法的不同实现,这些方法有关系,因为都诣在完成相同的任务,只是不同的类用不同的方式。
* 隐藏:是指方法被替换成另一个方法,方法通常没关系,而且可能执行完全不同的任务。
*
* 注:对方法进行重写是有用的编程概念;而如果方法被隐藏,则意味着可能发生了一处编程错误(除非加上new关键字强调自己没错)。
*
*
*
*
* 3)接口
*接口------表示的是一个规范、能力
* [public] interface I...able
* {
* 成员;
* }
*
* 使用接口实现多态,要声明接口类型的变量去装子类的对象
*
* 注意:接口中的成员不允许添加访问修饰符,默认就是public;而类当中不加访问修饰符默认是private
* 接口中的方法没有方法体,即接口成员不允许有定义
*
* 接口的特点:
* 1)接口是一种规范
* 2)只要一个类继承了一个接口,那么这个子类就必须实现这个接口中所有的成员
* 3)为了多态,接口不能被实例化,也就是说接口不能创建对象,但可以装子类的对象
* 4)接口中的成员不能加“访问修饰符”,接口中的成员默认访问修饰符为public,不能被修改
* 5)接口中的成员不能有任何实现(无方法体),只是定义了一组未实现的成员
* 6)接口中只能有方法、属性、索引器、事件(本质都是方法),不能有字段和构造函数
* 7)接口与接口之间可以继承,并且可以多继承
* 8)接口不能去继承一个类,而类可以继承接口(接口只能继承于接口,类既可以继承接口,也可以继承类)
* 9)实现接口的子类必须实现该接口的全部成员
* 10)一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面,因为类是单继承的
*
*
* 显式实现接口的目的:解决方法的重名问题
* 什么时候显式的去实现接口: 当继承的接口中的方法和参数一模一样的时候,要用显式的实现接口
* 例:A接口中M()与子类重名,需要在子类中显示实现接口中的成员
* void A.M()
* {
* 方法体;
* }
*
* 子类对象调用的是同名方法中本类的方法,接口类型的变量所装的子类对象调用的是显式实现接口所定义同名方法
*
* 当一个抽象类实现接口的时候,需要子类去实现接口
*
*/
*
*/
3.简单工厂设计模式
核心:根据用户的输入创建子类对象赋值给父类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _03简单工厂设计模式
{
class Program
{
static void Main(string[] args)
{
//2、设计模式:设计这个项目的一种方式
//3、简单工厂设计模式------设计给用户卖笔记本
Console.WriteLine("请输入您喜欢的电脑品牌:");
string brand = Console.ReadLine();
NoteBook nb = GetNoteBook(brand); //返回父类类型的对象,父类直接调用装的子类对象的重写的方法,一句程序就可以,也减少了代码的冗余,减少了子类之间的差异性
nb.SayHello();
}
/// <summary>
/// 简单工厂设计模式的核心: 根据用户的输入创建子类对象赋值给父类
/// </summary>
/// <param name="brand"></param>
/// <returns></returns>
public static NoteBook GetNoteBook(string brand)
{
//======================根据用户输入来确定父类中装的是哪个子类对象。
//=====多态的另一个特点:减少了子类之间的差异性
NoteBook nb = null;
switch(brand)
{
case "Apple":nb = new Apple();
break;
case "Acer":nb = new Acer();
break;
case "Lenovo":nb = new Lenovo();
break;
case "Mac":nb = new Mac();
break;
}
return nb;
}
}
}
4.什么时候用虚方法、抽象类、接口去实现多态
/*
* 什么时候用虚方法来实现多态? virtual override
* 答:在提供出来的几个类当中,如果说能够抽象出来一个类作为父类,这个父类当中有这几个子类共有的方法,如果说父类可以实现该方法,并且还需要创建这个父类的对象,那么这个时候就使用虚方法。
*
* 什么时候用抽象类来实现多态? abstract override
* 答:在提供出来的几个类当中,如果说能够抽象出来一个类作为父类,这个父类当中有这几个子类共有的方法,如果说父类不知道如何去实现该方法,则使用抽象类。
*
* 什么时候用接口来实现多态? interface
* 答:如果说这几个类中不能抽象出一个父类,但是,它门都有一个共同的行为,共同的能力,这个时候就使用接口来实现多态。
*
*
*/
5.产生一个不会重复的编号
Console.WriteLine(Guid.NewGuid().ToString());