如果签名相同的⽅法在基类和派⽣类中都进⾏了声明,但是该⽅法没有分别声明为virtual 和override,派⽣类就会隐藏基类⽅法。(要使⽤new关键字进⾏声明)
public new void AI()
{
Console.WriteLine("Boss自己的AI");
}
这样就把基类里的同名方法隐藏掉了
修饰符
修饰符,⽤来类型或者成员的关键字。修饰符可以指定⽅法的可⻅性。
public:
同⼀程序集(DLL或EXE)中的任何其他代码或引⽤该程序集的其他程序集都可 以访问该类型或成员。 private: 只有同⼀类或结构中的代码可以访问该类型或成员。
protected:
只有同⼀类或结构或者此类的派⽣类中的代码才可以访问该类型或成员。
internal:
同⼀程序集中的任何代码都可以访问该类型或成员,但的代码不可以。
protected internal:
在⼀程序集中,protected internal体现的是internal的性质;在其 他程序集中,protected internal体现的是protected的性质。
public 和private修饰字段和⽅法的时候,表⽰该字段或者⽅法能不能通过对象去访问,只 有public的才可以通过对象访问,private(私有的)只能在类模板内部访问。
protected
保护的,当没有继承的时候,它的作⽤和private是⼀样的,当有继承的时候, protected表⽰可以被⼦类访问的字段或者⽅法 类的修饰符 public class ... class ... 前者可以在别的项⽬下访问,后者不⾏ 其他修饰符
new
隐藏继承的成员
abstract
使⽤abstract修饰的类为抽象类,抽象类只能是其他类的基类,不能与sealed、static⼀起 使⽤。 abstract可以修饰抽象类中的⽅法或属性,此时,⽅法或属性不能包含实现,且访问级别 不能为私有。 抽象类不能被实例化。
sealed
使⽤sealed修饰的类为密封类,密封类⽆法被继承,不能和abstract、static⼀起使⽤。 当sealed⽤于⽅法或属性时,必须始终与override⼀起使⽤。
static
使⽤static修饰的类为静态类,静态类所有成员都必须是静态的,不能与abstract、sealed ⼀起使⽤。 static可以修饰⽅法、字段、属性或事件,始终通过类名⽽不是实例名称访问静态成员, 静态字段只有⼀个副本。 静态类不能被实例化。可以用静态字段模拟全局变量。存放在静态存储区域中共享。静态函数只能使用静态数据,不能使用变量。
const
使⽤const关键字来声明某个常量字段或常量局部变量,必须在声明常量时赋初值。 不能与static⼀起使⽤,常量默认是static的,常量字段只有⼀个副本。
readonly
使⽤readonly关键字来声明只读字段。 只读字段可以在声明或构造函数中初始化,每个类或结构的实例都有⼀个独⽴的副本。 可以与static⼀起使⽤,声明静态只读字段。 静态只读字段可以在声明或静态构造函数中初始化,静态常量字段只有⼀个副本。
virtual
virtual关键字⽤于修饰⽅法、属性、索引器或事件声明,并使它们可以在派⽣类中被重 写。 默认情况下,⽅法是⾮虚拟的。 不能重写⾮虚⽅法。 virtual修饰符不能与static、abstract、private或override修饰符⼀起使⽤。
override
要扩展或修改继承的⽅法、属性、索引器或事件的抽象实现或虚实现,必须使⽤override 修饰符。 重写的成员必须是virtual、abstract或override的。
添加别的项目中类的引用
1、添加别的项目的引用 2、引入命名空间 3、把类设置为public
接口继承
interface Interface1
{
void Method1();
}
interface Interface2:Interface1
{
void Method2();
}
接口2继承了接口1,但并不需要实现接口1里的方法,而继承了接口二的类要实现接口2里的两个方法
class ClassInterface2 : Bird,Interface2,Interface1
{
public void Method1()
{
}public void Method2()
{
}
}
集合类 列表List
当我们有很多类型⼀样的数据的时候,前⾯我们⼀般使⽤数组来进⾏管理,但是这样有个 缺点就是数组的⼤⼩是固定的。如果我们很多类型⼀样的数据,⽐如游戏得分,我们可以 集合类来进⾏管理,⽐如列表List,我们可以使⽤列表List很⽅便的添加数据,删除数据 还有其他对数据的操作。
列表List的创建和使⽤
1,创建列表(列表可以存储任何类型的数据,在创建列表对象的时候⾸先要指定你要创建 的这个列表要存储什么类型的)(泛型)
List<int> list = new List<int>();
List<int> list = new List<int>() { 321, 653, 832 };
List<string> list = new List<string>();
2.用list.add()插入数据
3,如何取得列表中的数据?列表中的数据跟数组有点相似,索引从0开始 ,可以通过索引 来访问 scoreList[0] //访问添加到列表中的第⼀个数据
关于列表的更多内容
1,列表内部数据是使⽤数组进⾏的存储,⼀个空的列表内部会有⼀个⻓度为0的数组,当 给列表中添加元素的时候,列表的容量会扩⼤为4,如果添加第5个的时候,列表的⼤⼩ 会重新设置为8,如果添加第9个元素,列表容量会扩⼤为16,依次增加。当列表的中的 容量发⽣改变的时候,它会创建⼀个新的数组,使⽤Array.Copy()⽅法将旧数组中的元素 复制到新数组中。为了节省时间,如果事先知道要存储的数据的个数,就可以利⽤列表的 构造函数指定列表的容量⼤⼩,⽐如下⾯的 List intlist = new List(10);创建了⼀个初始容量为10的列表,当容量不够⽤的时 候,每次都会按照原来容量的2倍进⾏扩容。
我们可以通过Capacity属性获取和设置容量 intList.Capacity = 100;
2,注意容量和列表中元素个数的区别,容量是列表中⽤于存储数据的数组的⻓度通过Ca pacity获取,列表中的元素是我们添加进去需要管理的数据,通过Count获取
列表的遍历
遍历列表有两种⽅式:
1,for循环,遍历所有的索引,通过索引访问列表中的元素
for(int i=0;i<list.count;i++)
{循环体}
2,foreach遍历
foreach(int temp in list){ //依次取得list中的每⼀个元素赋值给temp,并执⾏循环体 //循环体 temp }
操作列表的属性和⽅法
1,Capacity获取容量⼤⼩
2,Add()⽅法添加元素
3,Insert()⽅法插⼊元素
4,[index]访问元素
5,Count属性访问元素个数
6,RemoveAt()⽅法移除指定位置的元素
7,IndexOf()⽅法取得⼀个元素所在列表中的索引位置 LastIndexOf()上⾯的⽅法是从前往后搜索,这个是从后往前搜索,搜索到满⾜条件的 就停⽌ 上⾯的两个⽅法,如果没有找到指定元素就返回-1
8,Sort()对列表中是元素进⾏从⼩到⼤排序
泛型
通过参数化类型来实现在同⼀份代码上操作多种数据类型。利⽤“参数化类型”将类型抽象 化,从⽽实现灵活的复⽤。
定义⼀个泛型类就是指的是,定义⼀个类,这个类中某些字段的类型是不确定的,这些类 型可以在类构造的时候确定下来。
定义
class ClassA<T> //Type int string double
{// MyClass
private T a;
private T b;
public ClassA(T a, T b)
{
this.a = a;
this.b = b;
}
public T GetSum()
{
dynamic num1 = a;
dynamic num2 = b;
dynamic result = num1 + num2;
return (T)result;
//return a + b; 这样写会报错,因为不确定a,b的类型
}
}
public static T GetSum<T>(T a,T b)
{
dynamic num1 = a;
dynamic num2 = b;
return (T)(num1 + num2);
}
int result = GetSum<int>(45, 12);
使用
public override string ToString()
{
string result = age + ":" + name;
return result;
}
每个类里都有一个ToString的可以被子类重写的方法,如果不重写就调用父类里的方法,override重写就调用子类里重写了的方法。