文章目录
1.VOB
(1)多态的概念
多态按字面的意思就是"多种状态"
让继承同一父类的子类们 在执行相同方法时 却有不同的表现(状态)
主要目的
同一父类的对象 执行相同行为(方法) 有不同的表现
解决的问题
让同一个对象有唯一行为的特征
(2)解决的问题
class Father
{
public void SpeakName()
{
Console.WriteLine("Father的方法");
}
}
class Son : Father
{
public new void SpeakName()
{
Console.WriteLine("Father的方法");
}
}
(3)多态的实现
我们目前已经学过的多态
编译时多态 – 函数重载 开始就写好的
我们将学习的:
运行时多态(vob 抽象函数 接口)
我们今天学习 vob
v:virtual(虚函数)
o:override(重写)
b:base(父类)
class GameObject
{
public string name;
public GameObject(string name)
{
this.name = name;
}
// 虚函数 可以被子类重写
public virtual void Atk()
{
Console.WriteLine("游戏对象进行攻击");
}
}
class Player : GameObject
{
public Player(string name):base(name)
{
}
// 重写虚函数
public override void Atk()
{
// base 的作用
// 代表父类 可以通过 base 来保留父类的行为
base.Atk();
Console.WriteLine("玩家对象进行攻击");
}
}
class Monster : GameObject
{
public Monster(string name) : base(name)
{
}
public override void Atk()
{
Console.WriteLine("怪物对象进行攻击");
}
}
(4)解决的问题
Father f = new Son();
f.SpeakName();
(f as Son).SpeakName();
(5)多态的使用
GameObject p = new Player("唐老狮");
p.Atk();
(p as Player).Atk();
GameObject m = new Monster("小怪物");
m.Atk();
(m as Monster).Atk();
2.抽象类和抽象函数
(1)抽象类
概念
被抽象关键字 abstract 修饰的类
特点:
1.不能被实例化的类
2.可以包含抽象方法
3.继承抽象类必须重写其抽象方法
abstract class Thing
{
// 抽象类中 封装的所有知识点 都可以在其中书写
public string name;
// 可以在抽象类中写抽象函数
}
class Water : Thing
{
}
(2)抽象函数
又叫纯虚方法
用 abstract 关键字修饰的方法
特点:
1.只能在抽象类中申明
2.没有方法体
3.不能是私有的
4.继承后必须实现 用 override 重写
abstract class Fruits
{
public string name;
// 抽象方法是一定不能有函数体的
public abstract void Bad();
public virtual void Test()
{
// 可以选择是否写逻辑
}
}
class Apple : Fruits
{
public override void Bad()
{
}
// 虚方法是可以由我们子类选择性来实现的
// 抽象方法必须要实现
}
class SuperApple :Apple
{
// 虚方法和抽象方法都可以被子类无限的去重写
public override void Bad()
{
base.Bad();
}
public override void Test()
{
base.Test();
}
}
(3)使用
// 抽象类不能被实例化
// Thing t = new Thing();
// 但是可以遵循里氏替换原则 用父类容器装子类
Thing t = new Water();
3.接口
(1)接口的概念
接口是行为的抽象典范
它也是一种自定义类型
关键字:interface
接口申明的规范
1.不包含成员变量
2.只包含方法 属性 索引器 事件
3.成员不能被实现
4.成员可以不用写访问修饰符 不能是私有的
5.接口不能继承类 但是可以继承另一个接口
接口的使用规范
1.类可以继承多个接口
2.类继承接口后 必须实现接口中所有成员
特点:
1.他和类的申明类似
2.接口是用来继承的
3.接口不能被实例化
(2)接口的申明
// 接口关键字:interface
// 语法:
// interface 接口名
// {
// }
// 一句话记忆:接口是抽象行为的"基类"
// 接口命名规范:帕斯卡前面加个I
interface IFly
{
void Fly();
string Name
{
get;
set;
}
int this[int index]
{
get;
set;
}
event Action doSomthing;
}
(3)接口的使用
// 接口用来继承
class Animal
{
}
// 1.类可以继承一个类 n 个接口
// 2.继承了接口后 必须实现其中的内容 并且必须是 public 的
class Person : Animal, IFly
{
// 3.实现的接口函数 可以加 v 在子类重写
public virtual void Fly()
{
}
public string Name
{
get;
set;
}
public int this[int index]
{
get
{
return 0;
}
set
{
}
}
public event Action doSomthing;
}
(4)接口可以继承接口
// 接口继承接口时 不需要实现
// 待类继承接口后 类自己去实现所有内容
interface IWalk
{
void Walk();
}
interface IMove : IFly,IWalk
{
}
class Test : IMove
{
public int this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public event Action doSomthing;
public void Fly()
{
throw new NotImplementedException();
}
public void Walk()
{
throw new NotImplementedException();
}
}
(5)显示实现接口
// 当一个类继承两个接口
// 但是接口中存在着同名方法时
// 注意:显示实现接口时 不能再写访问修饰符
interface IAtk
{
void Atk();
}
interface ISuperAtk
{
void Atk();
}
class Player : IAtk, ISuperAtk
{
// 显示实现接口就是用 接口名.行为名 去实现
void IAtk.Atk()
{
}
void ISuperAtk.Atk()
{
}
public void Atk()
{
}
}
(6)使用
// 接口也遵循里氏替换原则
IFly f = new Person();
IMove im = new Test();
IFly ifly = new Test();
IWalk iw = new Test();
IAtk ia = new Player();
IAtk isa = new Player();
ia.Atk();
isa.Atk();
Player p = new Player();
(p as IAtk).Atk();
(p as ISuperAtk).Atk();
p.Atk();
4.密封方法
(1)密封方法概念
用密封关键字 sealed 修饰的重写函数
作用:让虚方法或者抽象方法之后不能再被重写
特点:和 override 一起出现
(2)实例
abstract class Animal
{
public string name;
public abstract void Eat();
public virtual void Speak()
{
Console.WriteLine("叫");
}
}
class Person : Animal
{
public override void Eat()
{
}
public override void Speak()
{
}
}
class WhitePerson : Person
{
public sealed override void Eat()
{
base.Eat();
}
public sealed override void Speak()
{
base.Speak();
}
}
#endregion
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("密封方法");
}
}