-
2022-02-09 17:35:58
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());
更多相关内容 -
C# 里氏转换与is、as用法
2022-03-12 09:08:41C# 里氏转换与is、as用法 1、里氏转换 1、子类对象可以赋值给父类 2、如果父类装的是子类对象,可以将这个对象强转化为子类的对象。 public class Person { public void SayHello() { Console.WriteLine("我是...C# 里氏转换与is、as用法
1、里氏转换
1、子类对象可以赋值给父类
2、如果父类装的是子类对象,可以将这个对象强转化为子类的对象。public class Person { public void SayHello() { Console.WriteLine("我是人类"); } } public class Student:Person { public void SayHello() { Console.WriteLine("我是学生类"); } } class Program { static void Main(string[] args) { Person p = new Student();//子类对象可以赋值给父类 p.SayHello();//输出:我是人类 ((Student)p).SayHello();//强转化为子类对象,输出:我是学生类 Console.ReadKey(); } }
2、is与as的用法
is:表示类型转换,能够将对象的类型进行转换就返回True,不能就返回False
as:表示类型转换,能够将对象的类型进行转换就返回对象,不能就返回nullpublic class Person { public void SayHello() { Console.WriteLine("我是人类"); } } public class Student:Person { public void SayHello() { Console.WriteLine("我是学生类"); } } public class Teacher:Person { public void SayHello() { Console.WriteLine("我是教师类"); } } class Program { static void Main(string[] args) { Person p = new Student(); //1.is用法 if(p is Student) { Console.WriteLine("可以将对象转化为子类对象");//输出 } if(p is Teacher) { Console.WriteLine("可以将Person对象转化为Teacher对象"); } //2.as用法 Student stu = p as Student; Teacher tch = p as Teacher; if(stu != null) { Console.WriteLine("stu不为空.");//输出 } if(tch != null) { Console.WriteLine("tch不为空."); } Console.ReadKey(); } }
注意:当判断类对象是否可以转换时,【is】可以判断是否可以转换为一个没有继承关系的类。但是【as】就不能直接转换为一个没有继承关系的类,不仅不会返回null,还会报错。
【is】判断转换为一个没有继承关系的类时,会警告,但不会报错。
【as】转换为一个没有继承关系的类时,会报错!
因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。
-
C#里氏转换
2020-12-14 17:09:22里氏转换 之前匆匆忙忙学过里氏转换,但是又忘了,今天写下博客来记录吧。 概念:1 可以将子类对象(派生类)赋值给父类(基类)对象 父类:Person person=new Child(); 例子: 上图就是一个简单例子:将...里氏转换
之前匆匆忙忙学过里氏转换,但是又忘了,今天写下博客来记录吧。
概念:1 可以将子类对象(派生类)赋值给父类(基类)对象
父类:Person person=new Child();
例子:
上图就是一个简单例子:将字符串数组ABC通过分隔符“|”进行分割,结果如黑窗口所示。
重点:请看红笔划得地方,join("分隔符","params object[]value"),本来join方法里的参数是object类型的数组,但是这里却改写为string[]{...}
原因:object是父类,而string是子类,可以将子类直接赋值给父类。
2 如果父类里放的是子类对象,那么就可以将父类对象强制转化为子类对象。
Person person=new Child();
Child child=(Child)person;
例子:
这个例子主要就是定义了父类person ,子类student,teacher, person类型的数组,里面存放了子类对象(student,teacher),和本类对象(person)。
当遍历数组,想输出各个对象的方法。请看红笔划的地方,将父类对象(sj[i])强转为子类,然后输出子类的方法。这就验证了里氏转换的第二个原则。
这篇文章的内容也是看了视频所写,旨在记录学习的过程,如有错误,还望指正,谢谢。
转载于:https://www.cnblogs.com/sjitLearn/p/8875553.html
目录
-
C# 里氏转换原则
2018-12-29 18:00:02里氏转换原则 父类转换为子类(显示转换): case1 Person p = new Person(); Person p1 = new Student ();//new的是子类,调的是父类的方法,实际上调用的是父类的方法 case2 Person p = new Person(); Student ...优点
1. 提高代码的重用性,子类拥有父类的方法和属性;
2. 提高代码的可扩展性,子类可形似于父类,但异于父类,保留自我的特性。类型转换
显示转换:父类对象转换为子类类型必须使用强制转换
case1
Person p = new Person(); Person p1 = new Student ();//转换失败,实际上调用的是父类的方法
case2
Person p = new Person(); Student stu = (Student)p;//转换失败 stu.SayHello();
case3
Person p = new Teacher(); Teacher t = (Teacher)p;//转换成功 t.SayHi();
隐式转换:子类对象转换为父类类型可以直接转
Student stu = new Student();//转换成功 Person p = stu; p.Show();
关键字is/as转换:
is转换:返回的是bool值,true为能转换,false不能转换。
as转换:使用as转换时,如果转换不了,不报异常,返回值为Null.在调用方法时报异常。//关键字is转换 Person p = new Student();//父类转换为子类 bool result = p is Teacher; if(result ) { Teacher t=(Teacher)p; } else { Console.WriteLine("转换不了"); } Console.ReadKey();
//关键字as转换 Teacher t = new Teacher();//子类转换为父类 Person p = t as Person; p.PerShow(); Person p = new Teacher();//父类转换为子类 Teacher t = p as Teacher; t.TeaShow();
关键字is转换练习
随机生成类,调取生成类的方法。
static void Main(string[] args) { Person[] per = new Person[10];//将类放到一个数组 Random r = new Random();//随机数 for (int i = 0; i < per.Length ; i++) { int num = r.Next(1, 7); switch (num)//依据随机数调取类 { case 1: per[i]=new Teacher();break; case 2: per[i] = new Student();break; case 3: per[i] = new ShuaiGuo();break; case 4: per[i] = new MeiNv();break; case 5: per[i] = new YeShou();break; case 6: per[i] = new Person();break; } } for (int i = 0; i < per.Length ; i++) { SayType(per[i]); } Console.ReadKey(); } public static void SayType(Person p)//方法:随机调取类后调用其中的方法 { if(p is Teacher) { ((Teacher)p).PerShow(); } else if(p is Student ) { ((Student)p).StuShow(); } else if(p is ShuaiGuo) { ((ShuaiGuo)p).shuaiShow(); } else if(p is MeiNv) { ((MeiNv)p).MeiShow(); } else if(p is YeShou) { ((YeShou)p).YeShow(); } else if (p is Person) { ((Person)p).PerShow(); } }
-
C#里氏转换原则
2019-08-15 11:06:02显示转换:父类对象转换为子类类型必须使用强制转换 Person p = new Teacher(); Teacher t = (Teacher)p; //如果new的时候是new的是子类,那么在转换这个子类的时候可以 t.SayHi(); Person p = new Teac..... -
C#里氏转换is & as关键字使用示例
2020-09-03 19:02:50using System; ...namespace oop05_里式转换 { class Program { static void Main(string[] args) { // is使用示例 Person subStu = new Student(); // Student类继承自Person类 if (subStu -
C#--里氏转换
2021-04-05 16:01:401、里氏转换 1)、子类可以赋值给父类 2)、如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象。 2、子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。 3、 is:表示类型转换,... -
设计模式之里氏转换原则
2017-08-21 22:56:11设计模式之里氏转换原则 -
C#里氏转换练习(随机类型转换和对应方法调用)
2020-09-03 18:55:54using System; using System.Collections....namespace oop05_里式转换 { class Program { static void Main(string[] args) { Person[] per = new Person[10]; Random rd = new Random(); for (int i = 0; i -
C#基础-里氏转换
2021-09-23 08:21:591.里氏转换 1)、子类可以赋值给父类-如果有一个地方需要父类作为参数,我们可以给一个子类代替 2)、如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象 2.子类对象可以调用父类中的成员,但是父类对象... -
C# 里氏转换语法
2019-08-02 16:09:11里氏转换语法 子类可以赋值给父类: Student stu = new Student(); //子类对象 Person p = stu; //把子类赋值给父类 如果一个父类装的是子类的对象,那么父类可以直接强转成子类: Student stu1 = ... -
C#里氏转换以及练习
2017-10-30 15:49:52c#里氏转换练习,继承 -
c# 里氏转换
2018-07-03 13:43:53//里氏转换 } if (p[i] is t2) { ((t2)p[i]).t2H(); } if (p[i] is t3) { ((t3)p[i]).t3H(); } } for (int i = 0; i ; i++) //输出结果 { Console.WriteLine(p[i]); } Console.ReadKey(); } -
C#里氏转换(对象转型)
2020-08-29 18:06:13子类可以赋值给父类:即向上转型,子类对象可以调用父类的成员,但父类对象只能调用自己的成员。 ...向上转型:子类对象交给父类引用,父类引用指向子类对象。... -
C#里氏转换语法应用
2020-09-02 11:01:24C#里氏转换语法应用 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 里氏转换 { class Program { static void Main(string... -
c#里氏转换法
2018-01-23 15:49:02一,里氏转换的两个原则 1,子类可以赋值给父类,如果一个地方需要父类作为参数,我们可以给一个子类代替 ,但父类不会有子类的的字段,属性和方法 string str =string.Join("|",new string[] { "1", "2","3... -
C# 里氏转换(父类转换成子类)( is as )
2017-12-07 20:39:37里氏转换: 1、子类可以赋值给父类 2、如果父类中装的是子类对象,则可以将这个父类转换为对应的子类对象 ---->关键字 1、is:返回bool类型,指示是否可以做这个转换 2、as:如果转换成功,则返回对象,否则...