C#----类的继承及“衍生物”

1.什么是继承?

在C#里,很多类有相似的数据,它们有相似的属性,也有不同的,这时我们可以用继承来让某几个类来继承同一个类。任何类都可以从另外一个类继承,这就是说,这个类拥有它继承的类的所有成员。在面向对象编程中,被继承的类叫父类或基类。所有类默认继承object基类。

2.继承的类型

a.实现继承
简单地说,就是表示一个类型派生于一个基类型,它拥有基类所有的成员字段和函数。

b.接口继承
简单地说,表示一个类型只继承了函数的签名(返回类型,方法名,参数列表),没有继承任何实现代码。

3.继承的使用

新建一个项目,添加一个Enemy类,这个类里面的字段和函数成员如下:

class Enemy
    {
        private  int hp;
        private  float speed;
        public int HP
        {
            get
            {
                return hp;
            }
            set
            {
                hp = value;
            }
        }
        public float Speed { get; set; }
        public void AI()
        {
            Console.WriteLine("是Enemy的公有的AI方法");
        }
        public void Move()
        {
            Console.WriteLine("是Enemy的公有的Move方法");
        }

    }

再新添加一个Boss类,让它继承自Enemy类,如下所示:

class Boss:Enemy
    {
        public void Attack()//子类里自己新增的方法
        {
            AI();
            Move();
            Console.WriteLine("Boss正在进行攻击");
        }
    }

然后在项目里创建一个名为boss的对象,如下所示:

 class Program
    {
        static void Main(string[] args)
        {
            Boss boss = new Boss();
            boss.Attack();//继承:父类里所有的函数成员和数据成员都会被继承到子类里
        }
    }

返回结果为:
是Enemy的公有的AI方法
是Enemy的公有的Move方法
Boss正在进行攻击
解释:因为boss类继承了Enemy类,所以Enemy里的函数成员会被继承,同时boss类还有自己新的函数成员Attack().
还有一个小的知识点:

 class Program
    {
        static void Main(string[] args)
        {
           Enemy enemy = new Boss();//父类声明的对象,可以让子类去构造,但反过来不行。
            Boss boss = (Boss)enemy;//enemy虽然是父类去声明,但构造还是子类,所以本质上还是子类类型的,这里进行强制转换,转换成子类类型的
            boss.Attack();
        }
    }

返回结果和上面一样。
解释:一个对象是什么类型,看它是通过什么构造的,通过子类构造,那它就有子类里的函数和字段。

4.继承的“衍生物”

a.虚方法
在认识虚方法之前,先来了解多态,多态是面向对象编程的基本特征之一,它使得派生类的实例可以直接赋予基类的对象,然后直接就可以通过这个对象调用派生类的方法。在C#中,类的多态性是通过在派生类中重写基类的虚方法来实现的。
首先,我们在父类Enemy里写一个虚方法

class Enemy
    {
        public virtual void Move()
        {
            Console.WriteLine("是Enemy的公有的Move方法");
        }
    }

接着在子类Boss里重写这个虚方法:

class Boss:Enemy
    {
        public void Attack()//子类里自己新增的方法
        {
            Move();//调用的是子类重写的Move方法
            Console.WriteLine("Boss正在进行攻击");
        }
        public override void  Move()
        {
            Console.WriteLine("是boss的移动方法");
        }
    }

最后在项目里调用

class Program
    {
        static void Main(string[] args)
        {
            Boss boss = new Boss();
            boss.Attack();//继承:父类里所有的函数成员和数据成员都会被继承到子类里
        }
    }

返回结果
是boss的移动方法
Boss正在进行攻击
解释:我们在子类里重写了虚方法,之后不管在哪调用,都是调用了重写之后的方法。

b.隐藏方法
如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别用virtual和override关键字,那么派生类方法会隐藏基类方法。
码上代码

class Enemy
    {
        public void Move()
        {
            Console.WriteLine("是Enemy的公有的Move方法");
        }
    }
class Boss:Enemy
    {
        public new void Move()//隐藏:当子类里有一个和签名和父类相同的方法时,就会把父类中的那个方法隐藏。
        {
            Console.WriteLine("是boss的移动方法");
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            Boss boss = new Boss();
            boss.Move();
        }
    }

返回结果:
是boss的移动方法
请按任意键继续.

但是在项目里用父类来声明对象,那调用的是谁的方法呢?接着码上

class Program
    {
        static void Main(string[] args)
        {
            Enemy boss = new Boss();
            boss.Move();
        }
    }

返回结果:
是Enemy的公有的Move方法
请按任意键继续.

说明:如果是使用子类声明的对象,调用隐藏方法会调用子类的;如果是父类声明的,那么会调用父类的。

c.抽象类
如果一个类不与具体的事物相联系,而只是表达一种抽象的概念或行为,仅仅是作为其派生类的一个基类,这样的类就可以声明为抽象类。在抽象类中声明方法时,如果加上abstract关键字,则为抽象方法。类中只要有一个方法声明为抽象方法,这个类也必须声明为抽象类。
语法格式:
访问修饰符 abstract class 类名:基类或接口
{
//类成员
}

新添加一个Bird类,写一个抽象方法,让它的子类去实现这个抽象方法,码上代码

abstract class Bird  //一个抽象类就是一个不完整的模板,不能实例化对象
    {
        public float speed;
        public abstract void Fly();
    }

再添加一个Crow类,继承于它

 class Crow:Bird//继承一个抽象类,就必须去实现它里面所有的抽象方法,如果没有实现完所有的抽象方法,就必须定义为抽象类
    {
        public override void Fly()
        {
            Console.WriteLine("乌鸦在飞行");
        }
    }

在项目里声明对象去调用方法

class Program
    {
        static void Main(string[] args)
        {
             //Crow crow = new Crow();
            //crow.Fly();

            Bird bird = new Crow();//可以用抽象类去声明,但不可用它去构造,因为抽象类不完整
            bird.Fly();
    }

两种不同类型去声明对象都返回相同结果:
乌鸦在飞行
请按任意键继续.
总结:
1.一个类有抽象方法,则为抽象类,若一个类为抽象类,不一定有抽象方法;
2.若一个类继承于一个抽象类,那它要重写抽象类里所有抽象方法,否则就要被定义成抽象类。
3.可以用抽象类去声明对象,但不可用它去构造,因为抽象类不完整。

d.密封类和密封方法
C#里允许把类和方法声明为sealed。对于类,表示不能继承该类;对于方法,表示不能被重写。可以理解成一个类继承关系里的最后一层。

欢迎指正!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值