一、类的继承:
当几个类出现成员重复时,可以考虑把这些成员提取出来封装成一个类,作为这几个类的父类。
比如student、teacher、driver类都有人类的共性,可以将共性封装成一个person类,然后在三个类里加上继承,三个类就可以共用person类的成员
student、teacher、driver 子类 (派生类)
person 父类 (基类)
注意:子类继承了父类的属性和方法,但是没有继承父类的私有字段
二、继承的特性:
1、继承的单根性:一个子类只能有一个父类
2、继承的传递性:
查看类图:项目右键--->视图---->查看类图
问题:子类有没有继承父类的构造函数
答:子类并没有继承父类的构造函数,但是,子类会默认的调用父类的无参构造函数(构造函数一经改动,原先的默认构造函数就不复存在了)
所以,在父类重新写了一个有参数的构造函数之后,子类就调用不到父类的构造函数了,这时子类会报错
解决办法:
1)在父类重新写一个无参数的构造函数
2)在子类显示的调用父类的构造函数,使用关键字-----:base(父类构造函数的参数列表)
继承成员是new关键字:
1)创建对象
2)隐藏从父类那里继承过来的同名成员。隐藏的后果就是子类调用不到父类的同名成员
三、object类是所有类的基类
在C#中,所有类都直接或者间接的继承了object类
四、里氏转换
1、子类可以复制给父类: 好处------如果有一个地方需要一个父类做参数,我们可以给一个子类代替
例如:Student是Person的子类------> Student s = new Student; Person p = s;---->Person p = new Student;
用处:string str = string.Join("|", object) ; 这个地方object是所有类的父类,我们带入参数时可用:new string[]{"1","2"}
2、如果父类中装的是子类对象,那么我们是可以将这个父类转换为子类对象的
Person p = new Student;
Student ss = (Student)p; //强转
五、 is as
is:表示类型转换----如果转换成功,返回一个true,否则返回false
if(p is Reporter)
{
Reporter rr = (Reporter)p;
rr.ReportSayHello();
}
else
Console.WriteLine("转换失败");
as:表示类型转换-----如果能够转换则返回一个对应的对象,否则返回一个null
//as的用法
Reporter r = p as Reporter;
r.ReportSayHello();
六、protected,访问修饰符
受保护的:可以在当前类的内部和该类的子类中访问
七、集合:ArrayList
数组的局限:长度不可变、类型单一
集合比数组的优势:长度可以任意改变、类型随便
方法:
add(object);单个添加任意类型的数据给集合
addrange(object【】) :添加多个任意类型的数据给集合
clear() :清空集合
remove(object):删除单个集合,写谁删谁
removeAt(int):根据索引删除元素
RemoveRange(0,3):从索引出删除3个元素
Reverse() :反转
Sort():升序排列 ---不一定能用,最好同类型时使用
Insert(int x,object y):在x处插入单个数据元素y
InsertRange(int x,string【】 y):在x处插入多个数据元素
Contains(x):判断是否包含x,是返回true,否返回false
集合的长度问题:
每次集合中包含的元素个数(count)超过了可以包含的元素的个数(capcity)的时候,集合就会向内存中申请多开辟一倍的空间
来保证集合的长度一直够用
八、集合:Hashtable 键值对集合 ---- 类似于字典 :从首字母查到拼音,然后从拼音找到字
在键值对集合中, 我们是根据键去找值
调用:集合对象[键] = 值
***键必须是唯一的,而值是可以重复的
九、foreach循环
foreach(var item in collection) {}
var:推断型 ----根据值能够推断出类型 ----但必须初始化
C#是一门强类型语言:在代码当中,必须对某一个变量的类型有明确的定义。比如:int n =15;
JS是一门弱类型语言:不需要对变量的类型明确的定义,统一用var表示,系统会自动分配
用foreach循环输出Hashtable集合:
foreach(var item in ht.Keys) //var:推断型 ----根据值能够推断出类型
{
Console.WriteLine("键是{0},值是{1}",item,ht[item]);
}
十、List泛型集合:
与ArrayList方法几乎相同,不同的是List一般先规定数据类型
//创建泛型集合对象添加数据:
List<int> list = new List<int>();
list.Add(1);遍历输出:
list.Add(2);
list.AddRange(new int[] {1,2,3,4,5,6,7});
list.AddRange(list);
for(int i=0;i<list.Count;i++)List与ArrayList区别是,List规定了数据类型,所以可以与数组相互转换
Console.WriteLine(list[i]);
//List泛型集合可以转换成数组
int[] nums = list.ToArray();
//数组转集合
List<int> list = nums.ToList();
装箱和拆箱:
数据类型 ----> 引用类型:装箱
int n = 10; object o = n;
引用类型 -----> 数据类型:拆箱
int nn = (int)o;
看两种类型是否发生了装箱和拆箱,要看着两种类型是否存在继承关系!存在继承关系才有可能是装箱
因装箱拆箱时会耗费大量运行时间,程序最好避免装箱和拆箱,在添加元素时,ArrayList和Hashtable都会包含一个装箱的操作,而List没有
所以List集合比ArrayList集合效率高很多,一般来说,前两个集合已经很少使用,最好使用List集合
十一、字典集合:Dictionary
与Hashtable类似,方法也类似
Dictionary<int,string> dic = new Dictionary<int,string>();遍历输出字典集合的两种方法:
//遍历输出键值foreach(var item in dic.Keys){Console.WriteLine("{0}----{1}",item,dic[item]);}//更为方便的键值输出foreach(KeyValuePair<int,string> kv in dic)Console.WriteLine("{0}---{1}",kv.Key,kv.Value);