c#入门-继承,多态

继承

当多个类型具有相同的成员时,可以使用继承来少写代码。
继承语法为:类型名+冒号+被继承的类型名。

class 英雄
{
	public int hp;
}
class 艾希 : 英雄
{
	public void 万箭齐发(英雄 目标)
	{
		目标.hp -= 100;
	}
}
class 盖伦 : 英雄
{
	public void 致死打击(英雄 目标)
	{
		目标.hp -= 20;
	}
}
class 瑞兹 : 英雄
{
	public void 法术涌动(英雄 目标)
	{
		目标.hp -= 40;
	}
}

继承链

考虑以下继承关系:宝可梦->皮丘->皮卡丘->雷丘

如果直接继承的基类型也有他的直接继承类。
这样构成的链式继承关系,称为继承链。
当我们说继承关系时,说的是整个继承链上的类,而不是单指类的直接基类。

例如:
左边三个类都是雷丘的基类。
右边三个类都是宝可梦的派生类。

继承的限制

  1. 静态类不允许继承
  2. 结构不允许继承
  3. 继承链不能成环
  4. 只能指定一个直接基类进行继承

多态

继承的意义在于,派生类是完整的基类,具有基类的一切功能,可以当作基类使用。
也就是说,派生类的值可以赋值给基类类型的变量。

英雄 a = new 艾希();//可以直接声明

瑞兹 b = new 瑞兹();
英雄 c = b;//也可以用已有的变量进行赋值

这在我们的函数体中没有用。因为我们声明一个盖伦变量,当然是因为想用盖伦的专有成员。
但是,如果是作为函数的参数很有用。函数的参数也是声明变量
这导致在调用函数时,可以使用派生类型的值,作为参数传递进去。

艾希 Ashe = new 艾希();
瑞兹 Ryze = new 瑞兹();
盖伦 Galen = new 盖伦();

Ashe.万箭齐发(Ashe);
Ashe.万箭齐发(Ryze);
Ashe.万箭齐发(Galen);
Ryze.法术涌动(Ashe);
Ryze.法术涌动(Ryze);
Ryze.法术涌动(Galen);
Galen.致死打击(Ashe);
Galen.致死打击(Ryze);
Galen.致死打击(Galen);

不使用多态的结果

如果上述例子中不使用多态和继承,那么代码会是下面这样:

class 艾希
{
	public int hp;
	public void 万箭齐发(艾希 目标)
	{
		目标.hp -= 100;
	}
	public void 万箭齐发(盖伦 目标)
	{
		目标.hp -= 100;
	}
	public void 万箭齐发(瑞兹 目标)
	{
		目标.hp -= 100;
	}
}
class 盖伦
{
	public int hp;
	public void 致死打击(艾希 目标)
	{
		目标.hp -= 20;
	}
	public void 致死打击(盖伦 目标)
	{
		目标.hp -= 20;
	}
	public void 致死打击(瑞兹 目标)
	{
		目标.hp -= 20;
	}

}
class 瑞兹
{
	public int hp;
	public void 法术涌动(艾希 目标)
	{
		目标.hp -= 40;
	}
	public void 法术涌动(盖伦 目标)
	{
		目标.hp -= 40;
	}
	public void 法术涌动(瑞兹 目标)
	{
		目标.hp -= 40;
	} 
}

艾希类存在的意义,是因为他会技能万箭齐发。
可是他们三个的技能效果只是造成伤害,只需要访问你的hp字段就行了。 不关心你是否会万箭齐发。
同理,在他们的技能对盖伦和瑞兹造成伤害时,也不关心他们有什么技能,只关心他们的hp。

为什么使用多态

c#中的功能存在的意义,都可以用四个角度去思考。

  1. 语法糖:这个语法是不是有替代方案。如果有,那现在这种语法是不是比替代方案更方便,或是更安全。如果是的话,那么这个功能就是语法糖。例如属性,索引器。
  2. 多数量:你知道该怎么写了,但全部手写出来会死人。程序就是为了省人手而生的,如果反而要人断手,理念就很冲突了。数组,循环,函数都是考虑这个问题的。
  3. 不可预知:你现在看到的程序并不是这个程序的完全体。一个程序总是会需要扩展,变动的。如果每次变动都需要变动当前的程序,那结果是不可想象的。变量,选择都是这方面的例子。
  4. 限制使用者:一个程序的安全运行,必须在一定条件下。为了维护这个条件,不能让使用者想做什么就做什么。访问权限,密封,就是干这个的。

继承这个语法,一定程度实现了第2点的意义。但这不是重点,他的存在就是为多态服务的。
有了继承才能保证多态的实现。

而多态的意义,占了第2点第3点。
数量从上面的例子看到了,仅仅3个类就声明了9个重载。如果换成宝可梦,上万种类型,后果不堪设想。
而不可预知,你使用多态声明的方法都可以给后续的类型使用。即便你现在没有拿到那些类型,你不知道那里面有什么东西。你的方法也可以生效。当然,他们需要使用继承是他们的事。看到现在的难度比预知未来的难度小多了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值