三:继承
1.继承的类型:实现继承和接口继承
1).实现继承:表示一个类派生于一个基类,拥有该基类型的所有成员字段和函数。在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时。
2).接口继承:表示一个类型只继承函数的签名,没有继承任何实现代码。在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。
2.多重继承
c#不支持多重继承,为简化代码的繁琐,可以允许类型派生自多个接口---多重接口继承。这说明c#可以派生自另一个类和任意多个接口。准确地说,System.Object是一个公共的基类,所以每个c#(除了Object之外)都有一个基类,还可以有任意多个基接口。
3.实现继承
如果要声明派生自另一个类的一个类,就可以使用下面的语法:
class MyDerivedClass : MyBaseclass
{
// functions and data members here
}
如果类(或 结构)也 派生 自接 口,则用逗号分隔列表中的基类和接 口:
public class MyDerivedClass: MyBaseClass , IInterface1 , IInterface2
{
// etc.
}
下面写个例子,
基类敌人类( hp speed 方法 ai move )
派生出来两个类
boss类
type1enemy类
type2enemy类
具体实现如下:
1).先创建一个Enemy怪物类
class Enemy
{
private float hp;
private float speed;
public float HP
{
get { return hp; }
set { hp = value; }
}
public float Speed
{
get { return speed; }
set { speed = value; }
}
public void AI()
{
Console.WriteLine("这里是Enemy1的公有AI方法");
}
public void Move()
{
Console.WriteLine("这里是Enemy1的公有Move方法");
}
}
2).在创建一个Boss类继承自Enemy基类
class Boss : Enemy{
public new void Move()//当子类里面有一个签名和父类相同的方法的时候,就会把父类中的方法隐藏
{//隐藏: 只是把父类中的方法隐藏了,看不到了,实际这个方法还存在
Console.WriteLine("这里是Boss的移动方法");
}
public void Attack()
{
//AI();
//Move();
////hp = 100;
//HP = 100;//父类里面公有是数据和函数成员才可以在子类里面访问
Move();
Console.WriteLine("Boss正在进行攻击");
}
}
3).在创建Type1Enemy,Type2Enemy继承自Enemy
class Type1Enemy:Enemy {
}
class Type2Enemy:Enemy {
}
4).然后在Program下实现
class Program {
static void Main(string[] args) {
//Boss boss = new Boss();
////boss.AI();//继承:父类里面所有的数据成员和函数成员都会继承到子类里面
//boss.Attack();
//Enemy enemy;
//enemy = new Boss();//父类声明的对象,可以使用子类去构造 子类声明的对象不可以使用父类构造
////enemy虽然使用父类进行了声明,但是使用了子类构造,所以本质上是一个子类类型的,我们可以强制类型转换转换成子类类型
//Boss boss = (Boss)enemy;
//boss.Attack();
//Enemy enemy = new Enemy();
//Boss boss =(Boss) enemy;//一个对象是什么类型的 主要看它是通过什么构造的 这里enemy使用了父类的构造函数,所以只有父类中的字段和方法, 不能被强制转换成子类
}
4.虚方法
把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:
class MyBaseClass{
public virtual string VirtualMethod(){
return "Method is called in base class";
}
}
在派生类中重写另外一个函数时,要使用override关键字显示声明
class MyDerivedClass:MyBaseClass{
public override string VirtualMethod(){
return "Method is called in derivedclass.";
}
}
我们在子类里面重写虚函数之后,不管在哪里调用都是调用重写之后的方法
5.隐藏方法
如果签名相同的方法在基类和派生类中都进行了声明,但是该方法没有分别声明为virtual和override,派生类就会隐藏基类方法。(要使用new关键字进行声明)
基类
class MyBaseClass{
public int MyMethod(){
}
}
派生类(在派生类中把基类同名的方法隐藏掉了)
class MyDerivedClass :MyBaseClass{
public new void MyMethod() {
}
}
注意:只是把父类中的方法隐藏了,看不到了,实际这个方法还是存在的
6.this和base关键字
this可以访问当前类中定义的字段,属性和方法,有没有this都可以访问,有this可以让IDE-VS编译器给出提示,另外当方法的参数跟字段重名的时候,使用this可以表明访问的是类中的字段,base可以调用父类中的公有方法和字段,有没有base都可以访问,但是加上base.IED工具会给出提示,把所有可以调用的字段和方法罗列出来方便选择
例如:this.AI; base.AI;