一、概念类
1、为什么有继承?什么是继承?继承了哪些内容?继承如何表示?继承的特性?
①、为什么要有继承?
比如有一个Person类,一个Teacher类,一个Student类他们有相同的属性,要想给这些属性赋值,需要逐一赋值,代码冗余。所以才会有继承的概念,来减少代码冗余,复用代码。
②、什么是继承?
继承(inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。
③、继承了哪些?
继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。
④、继承在代码中如何表示?
⑤、继承的特征?
在C#中,所有的类都直接或间接的继承自Object类(当我们定义一个类的时候,如果没有写:继承一个类,那么这个类就继承了object类)
传递性:父类继承了爷类的所有属性和方法,子类继承父类的所有属性和方法,当然中间所有爷类的属性和方法也在其中,这样爷类的所有属性和方法就被一代代的遗传下去,当然父类的新属性和方法与子类的新属性也一样被全部传递给下一代
单根性:只能有一个父类,只能从一个父类中继承属性和方法,跟只能从一个父亲那继承DNA意思差不多。一个子类只有一个父类,一个派生类只有一个基类。例:一个儿子只有一个亲爹。
2、为什么要有类图?
未建立继承时的类图,孤立存在
建立继承后的类图
通过类图可以清晰的看出谁是父类(箭头指向),谁是子类。
3、修饰符private,public,protected
private:私有成员,在类的内部才可以访问。
public:公共成员,完全公开,没有访问限制。
protected:保护成员,该类内部和继承类中可以访问。
4、里氏替换原则(LSP):子类替换父类(现阶段个人理解,有待后期再深入)
任何基类可以出现的地方,子类一定可以出现(子类对象可以替换父类对象)。子类对象可以替换父类对象的原因是子类的范围和能力要大于或等于父类。
a、子类继承了父类,拥有了父类的属性和方法,所以子类至少等于父类,父类有的子类都有。
b、子类可以拓展和重写父类的方法,所以父类没有的,子类也可以有。
二、图类
值类型与引用类型的区别:
三、代码类
①、从给出的字符串中找出所有e的位置 ToCharArray()方法,IndexOf()方法
方法一: 字符数组ToCharArray()方法
string st = "aefegecebdfebdelelelsleoeooer";
char[] index = st.ToCharArray(); //将字符串转换为字符数组
for (int i = 0; i < st.Length - 1; i++) //遍历数组,寻找e
{
if (index[i] == 'e') //如果有e
{
Console.WriteLine(i); //则将下标写入控制台
}
}
Console.ReadKey();
方法二:索引IndexOf()方法
string st = "aefegecebdfebdelelelsleoeooer";
int index = st.IndexOf('e'); //查找含有e的下标,并将其赋值给index
int count = 0;
while (index != -1) //当index不等于-1时循环,等于-1则跳出循环
{
count++;
Console.WriteLine("第{0}个e的索引为{1}", count, index); //在控制台上写入index
index = st.IndexOf('e', index + 1); //从index+1索引处再次寻找e,并将值赋值值index
}
Console.ReadKey();
②、读电脑中的文本文件,书名大于10个字符的只显示8个剩余用...代替,书名与作者之间用|隔开,File.ReadAllLines()方法
在读取电脑中文件时,采用File.ReadAllLines()方法时会有两个重载:
采用第一个重载时,读取文件会出现以下问题:
读取出来的代码是乱码,要怎么办呢?
我们可以看一下在文本文档保存时会有一个编码类型
尝试一下第二个方法,会发现有ANSI的地方
所以,最终读取文件的代码为:
string path =@"C:\Users\Smile\Desktop\书.txt"; //找到文本文件路径
string[] str=File.ReadAllLines(path,Encoding.Default); //File类的方法,读取电脑中文本文档内所有行的内容,并默认其ANSI编码
for (int i = 0; i < str.Length; i++) //遍历读取的字符串数组
{
string[] text = str[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); //切割完后会有空白项,所以要用去除空白项的参数选项
//清晰繁琐版
if (text[0].Length >= 10)
{
Console.WriteLine(text[0].Substring(0, 8) + "...|" + text[1]);
}
else
{
Console.WriteLine(text[0] + "|" + text[1]);
}
//易混浓缩版
string st= text[0].Length >= 10? (text[0].Substring(0, 8) + "...|" + text[1]) : (text[0] + "|"+text[1]);
Console.WriteLine(st);
}
Console.ReadKey();
③、显示调用父类的构造方法,关键字:base
未使用父类构造方法前(代码冗余):
public Teacher(string name,char sex,int age,int salary)
{
this.Name = name;
this.Age = age;
this.Sex = sex;
this.Salary = salary;
}
使用父类构造方法后(精炼代码,减少冗余):
public Teacher(string name, char sex, int age, int salary):base(name,sex,age)
{
this.Salary = salary;
}
④、里氏替换原则
#region 子类父类转换四种情况
情况一:代码正确,运行报异常(父类转换为子类×)
Person p = new Person(); //实例化一个Person类为new Person类,实例名为p
Teacher t = new Teacher(); //实例化一个Teacher类为new Teacher类,实例名为t
Student stu = (Student)p; //强制转换,此段代码没有问题,但运行时出问题,父类对象不能直接转换为子类(父亲想当儿子×)
情况二:正确(子类转换为父类√:子类需要父类的方法或其他数据,此方式可以把子类转换为父类,从而使用父类方法)
Person p = new Teacher(); //实例化一个Person类为new Teacher类,实例名为p
Teacher t = (Teacher)p; //强制转换,如果父类new时是子类,那么在转换这个子类时,是可以的
情况三:代码正确,运行报异常(子类A转换为子类B×)
Person p = new Teacher(); //实例化一个Person类为new Teacher类,实例名为p
Student stu = (Student)p; //此段代码没有问题,但运行时报异常,new的子类是teacher子类,但不能转换为student子类(兄弟A转兄弟B×)
如果new 的是子类,转换的时候转的另一个子类,报异常
情况四:正确(子类转换为父类√)
Student stu = new Student();
Person p = stu; //子类转换为父类,是由低到高,可隐式转换。
#endregion
遇到上面这个情况怎么办,代码编写没有问题不会报错,但运行时会出错,这就需要进行判断
如何进行判断呢? is
Person p = new Person();
bool result = p is Teacher;
if (result) //判断是否能转换
{
Teacher t = (Teacher)p; //能转换则强制转换
t.TIntro();
}
else
{
Console.WriteLine("转换不了"); //不能转换则提示
}
Console.ReadKey();
转换判断(个人理解,若有不足还望大神给予指正^_^)
public static void Func(object p)
{
// 转换,然后调用特有方法
if (p is Teacher) //如果p is Teacher 值为true则执行大括号内容,否则跳过
{
Teacher t = (Teacher)p; //强制转换为Teacher类
t.TIntro(); //调用Teacher类方法
}
else if (p is Student) //如果p is Student 值为true,则执行大括号内容
{
Student stu = (Student)p; //强制转换为Student类
stu.SIntro(); //调用Student类方法
}
else if (p is Person) //如果p is Person 值为true,则执行大括号内容
{
((Person)p).PIntro (); //强制转换为Person类,调用Person类方法
}
else //否则
{
Console.WriteLine("传进来的不是可用类型"); //在控制台上显示信息
}
}
四、拓展类
里氏替换原则拓展:
https://www.iqiyi.com/v_19rr2xdetg.html