C#知识:继承、密封类、密封方法、重写
继承是面向对象的三大特性之一,通过继承能够减少重复代码的编写,有助于提升开发效率。
1、继承
- C#不同于C++,只支持单继承
- 当子类出现与父类同名的成员时,父类成员被隐藏(不同于重写)
- 子类继承父类所有成员(包括私有成员)
- 个人猜想:子类对象(this表示)中包含了父类对象(base表示)
- 成员隐藏不会改变子类中父类对象的成员(new关键字不加隐藏也生效)
- 成员重写会改变子类中父类对象的成员
2、里氏替换原则原则
- 父类变量容器装载子类对象
3、is和as
- is用来判断对象是否是指定类或其子类的对象,返回一个bool
- as用来将对象强转成指定类的对象,成功返回指定类对象,失败返回null
Animal animal2 = frog;
animal2.Run(); //动物跑
if (animal2 is Frog) //青蛙跑
(animal2 as Frog).Run();
4、继承中的构造函数
- 每个类默认有一个无参构造
- 用户自己定义了有参构造后,默认的那个无参构造会消失
- 所以一般用户定义有参构造后,还要定义无参构造
- 可以通过this关键字调用其他重载的构造
- 执行构造函数时,先执行爷爷类构造,再父类构造,最后子类构造
- 子类可以通过base关键字来调用父类构造
- 子类如果没显示调用父类的构造,则会默认调用父类的无参构造
5、运行时多态与方法重写
- 父类变量(容器)调用指定方法,实际调用的是它指向的子类对象实现的方法
- 重写之Vob:virtual、override、base
- virtual成员不能是private的
- 标记为override的成员不能被标记为new或virtual
- virtual只要出现一次,其子类后代都可以override
- override可以重写virtual、abstract、override方法
6、密封类
- 使用seal关键字修饰的类
- 无法被继承
7、密封方法
- seal一般与override一起出现
- 保护方法不被重写
- 子类可以用new隐藏父类的密封密封方法
8、完整代码示例:
namespace LearnExtend
{
class Creature
{
public float weight;
private float volumn; //父类私有变量子类无法直接访问
public Creature() => Console.WriteLine("生物的无参构造");
public Creature(float weight, float volumn)
{
this.weight = weight;
this.volumn = volumn;
Console.WriteLine("生物的有参构造");
}
public void Run() => Console.WriteLine("生物跑");
public virtual void SelfIntroduce() => Console.WriteLine("我是生物");
public virtual void func() => Console.WriteLine("生物密封函数");
}
class Animal : Creature
{
public float speed;
public Animal() => Console.WriteLine("动物的无参构造");
public Animal(float weight, float volumn, float speed):base(weight, volumn)
{
this.speed = speed;
Console.WriteLine("动物的有参构造");
}
public new void Run() => Console.WriteLine("动物跑"); 隐藏父类的方法
public override void SelfIntroduce() //重写父类方法
{
//base.SelfIntroduce();
Console.WriteLine("我是动物");
}
public sealed override void func() => Console.WriteLine("动物密封函数");
}
class Frog:Animal
{
public string color;
public new float speed; //隐藏父类成员变量
public Frog()
{
this.color = "绿色";
Console.WriteLine("青蛙的无参构造");
}
public Frog(float weight, float volumn, float speed, string color):base(weight, volumn, speed)
{
this.color = color;
Console.WriteLine("青蛙的有参构造");
}
public new void Run() => Console.WriteLine("青蛙跑"); //隐藏父类的方法
public override void SelfIntroduce() //重写父类方法
{
Console.WriteLine("波浪浪");
}
public new void func() => Console.WriteLine("青蛙密封函数");
}
internal class Program
{
//里氏替换原则原则
//父类变量容器装载子类对象
static void SomeoneSpeak(Creature someone)
{
someone.SelfIntroduce(); //重写 体现了运行时多态
someone.Run(); //隐藏 没有体现多态
}
static void Main(string[] args)
{
//里氏替换原则原则
//父类变量容器装载子类对象
Frog frog = new Frog(); //生物的无参构造 动物的无参构造 青蛙的无参构造
Animal animal = new Animal(1, 2, 3); //生物的有参构造 动物的有参构造
SomeoneSpeak(frog); //波浪浪 生物跑
SomeoneSpeak(animal); //我是动物 生物跑
Animal animal2 = frog;
animal2.Run(); //动物跑
if (animal2 is Frog) //青蛙跑
(animal2 as Frog).Run();
}
}
}
9、参考资料:
- 《唐老狮C#》
本篇结束,感谢您的阅读~