1.sealed关键字
sealed修饰的类是不可以被继承,也就是说不能派生子类,这样的类通常被称作密封类。
sealed修饰的方法是不可以被子类重写的
namespace 密闭类与密闭方法
{
class Program
{
static void Main(string[] args)
{
}
}
#region 密封类
//sealed class Animal//被sealed关键字修饰的类是不能被继承的
//{
// public void Shout()
// {
// Console.WriteLine("动物在叫! ");
// }
//}
//无法从密封类型“Animal”派生,会直接报错
//class Dog : Animal
//{
//}
#endregion
class Anmial
{
public virtual void Shout()//**虚方法,关键词virtual**
{
Console.WriteLine("动物在叫!");
}
}
class Dog : Anmial
{
public sealed override void Shout()//**重写方法的关键词是override ,sealed这里加上了之后,它的子类就没有办法再重写这个方法**
{
Console.WriteLine("狗在叫!");
}
}
class Xiao:Dog
{
//public override void Shout()//Dog.Shout()是密封的,无法进行重写
//{
//}
}
}
2.多态
多态就是指同一操作作用于不同的对象,会产生不同的结果。
再继承关系中,子类会自动继承父类的方法,但有时父类的方法不能满足子类的需求,那么可以对父类的方法进行修改。
当重写父类的方法时,要求子类的方法名,参数类型,参数个数必须于父类的完全一致,而且父类方法必须要用virtual关键字修饰,子类方法必须使用override关键字修饰。被virtual关键字修饰的方法称作虚方法
子类重新父类的方法时,不能使用比父类中被重写的方法更严格的访问修饰符
再C#中为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。而实现多态的方式有多种,重写也是多态的一种,
举例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 多态
{
class Program
{
static void Main(string[] args)
{
Cat an1 = new Cat();//这种被AnimalShout()方法调用时,实际是先调用再转换类型
Dog an2 = new Dog();//这种被AnimalShout()方法调用时,实际是先调用再转换类型
Animal an3 = new Cat();//创建cat对象,使用animal类型变量引用,这里是是先转换类型再调用
Animal an4 = new Dog();//创建dog对象,使用animal类型变量引用,这里是是先转换类型再调用
AnimalShout(an1);//调用方法
AnimalShout(an2);
AnimalShout(an3);
AnimalShout(an4);
Console.ReadKey();
Console.ReadKey();
}
//Animal类型的参数
public static void AnimalShout(Animal an)//创建一个方法用来接收animal类型的参数
{
an.Shout();//实质上是因为父类的这个方法被修改,所以不管是那种形式,输出的都是子类的方法,也就是说只有对父类的方法重写了,才调用的是子类的方法
an.Test();//这里只会调用Animal类的方法,因为子类没有对父类进行修改
}
}
//定义一个共同的父类
class Animal
{
public virtual void Shout()//虚方法,子类可以进行重写
{
Console.WriteLine("动物在叫!");
}
public void Test()//定义一个测试方法,并且子类也有一个,且这个父类的测试方法被隐藏基类方法
{
Console.WriteLine("test");
}
}
//定义一个狗类继承动物类
class Dog:Animal
{
public override void Shout()//修改父类方法override。
{
Console.WriteLine("狗在叫!");
}
public new void Test()//test方法
{
Console.WriteLine("test子类");
}
}
//再定义一个毛类继承动物类
class Cat:Animal
{
public override void Shout()//修改父类方法override。
{
Console.WriteLine("猫在叫!");
}
}
}
3.base关键字
当子类重写父类的方法后,子类对象将无法直接访问父类被重写的方法,base关键字专门用于在子类中访问父类的成员。例如方法父类的字段、方法、构造方法等。
语法格式:
base.字段名
base.方法名([参数1,参数2,……])
base() 访问构造方法。这个调用的地方是在子类的构造方法后面加上冒号在加上这个关键字括号,括号里填几个参数就调用父类的几个参数的构造方法,默认不填就调用无参的构造方法