(一)重写
简单来说就是子类对父类方法的扩展或者改写,重写是要再继承的基础上,我们定义两个类NewClass,WithClass,使其WithClass继承自NewClass,在父类和子类中都定义了一个名Add的方法,父类中我们加入关键字virtual子类中我们加入override关键字,这样一个简单的重写就构建完毕了。
class NewClass
{
public virtual void Add()
{
Console.WriteLine(123);
}
}
class WithClass : NewClass
{
public override void Add()
{
Console.WriteLine(456);
}
}
也就是说构建重写不单单要在继承的基础上,同时也需要在父类中添加virtual关键字,在子类中添加override关键字,如果不加这两个关键字的话,在新的版本中编辑器是允许的,会发出警告,但是在一些老版本中如果父类不加virtual关键字,子类不加override关键字,那么就会对子类方法进行隐藏,调用不了。
如果父类中的方法带有关键字internal,也就是他限制访问的话,子类是不能对其进行重写的,会提示当重写“internal”继承成员“NewClass.Add()”时,无法更改访问修饰符。
重写发生的条件:函数成员,访问修饰符,签名一致,在调用的时候,我们同样可以使用父类来对子类进行实例化对象。
NewClass w = new WithClass();
w.Add();
Console.ReadLine();
我们执行上面代码,可以看到打印出来的是被重写出来的方法。
(二)多态
当我们用一个父类的变量引用一个子类的实例的时候,在调用被重写的方法的时候,会调用最新的那个重写方法。
我们再创建一个类HearClass使其继承自WithClass类,里面不写如何方法,也不对Add方法进行重写,我们使用NewClass类来调用HearClass类。
class HearClass : WithClass
{
}
NewClass w = new HearClass();
w.Add();
Console.ReadLine();
调用继承的方法Add,运行上面代码,我们可以看到,打印出来的是该链中被重写的最新方法。
如果都对Add方法进行了重写,那么具体调用Add方法的要根据创建的实例化对象来决定,这里我对NewClass创建实例化对象。
NewClass w = new NewClass();
w.Add();
Console.ReadLine();
我们看到,运行出来显示的就是NewClass类中的Add方法。
(三)抽象类
指示某个类仅用作其他类的基类,而不用于自行进行实例化。 标记为抽象的成员必须由派生自抽象类的非抽象类来实现。定义抽象类的关键字为abstract,也就是说使用了abstract关键字将类定义为抽象类,是不能实例化自己本身的,且是不能说明主体的。
我们定义一个抽象类Student,里面有一个抽象方法Add。
abstract class Student
{
abstract public void Add();
}
我们可以看到我们是对这个类创建不了实例化对象的,我们可以看到提示无法创建抽象类的实例。
我们再向Add抽象方法中进行操作需要打印123,我们可以看到无法声明主体。由于抽象方法声明不提供实际的实现,因此没有方法主体;方法声明仅以分号结尾,且签名后没有大括号 ({ })。
我们使用的时候必须使用派生类来使用,我们这里定义一个NewStudent的普通类,使其继承Student,运用重写的方式来对Add方法进行使用,注意这里子类是需要携带override关键字的。
class NewStudent : Student
{
public override void Add()
{
Console.WriteLine(123);
}
}
在创建实例的时候,这种情况就不能使用父类来对其子类创建实例化对象了,只能由自身来对自身来创建实例对象。
NewStudent n = new NewStudent();
n.Add();
类似这样的纯抽象类,那么我们就可以理解为接口interface。
abstract class Student
{
abstract public void Add();
abstract public int Bdd();
abstract public string Cdd();
}
我们可以把上面这个全部由抽象方法组成的纯抽象类理解为一个interface接口,也就是下面这种形式。
interface Student
{
void Add();
int Bdd();
string Cdd();
}
抽象类中是可以定义普通方法的,只是定义的方法只能由派生类去使用,因为抽象类是创建不了实例化对象的。
abstract class Student
{
abstract public void Add();
public void Bdd()
{
Console.WriteLine(123);
}
}