C#视频—多态

什么是多态?

通俗的理解就是:不同的对象收到相同的消息时,会产生不同的行为。

多态的两种体现形式

1.重写父类方法

1)使用 new 关键字,隐藏父类方法
 当子类的方法与父类的方法同名时,可以在子类方法的修饰符后面加 new 关键字,这种是将父类的方法隐藏,我的理解是子类中仍然有继承下来的父类方法,只不过是隐藏起来。可以根据情况,想调用父类的方法就调用父类的方法,想调用自己的方法就调用自己的方法。
 如果不用 new 关键字,VS 会自动默认加上 new 关键字,但是会提示你:如果有意隐藏,请使用 new 关键字。

public class Person
{      
    public void Show()
    {
        Console.WriteLine("我是人别害怕");
    }        
}
public class Teacher : Person
{
    public new void Show()
    {
        Console.WriteLine("我是老师别害怕");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Teacher t = new Teacher();
        t.Show();
    }
}

//output:
//我是老师别害怕

2)虚方法重写
 将父类中的方法用 virtual 修饰,子类中用 override 关键字重写父类方法

public class Person
{      
    public virtual void Show()
    {
        Console.WriteLine("我是人别害怕");
    }        
}
public class Teacher : Person
{
    public override void Show()
    {
        Console.WriteLine("我是老师别害怕");
    }
}

注意:
   ①虚方法不能用 static 修饰
   ②虚方法不能用 private 修饰,因为虚方法就是让子类来重写的,如果声明为 private,子类就无法重写,所以不能是私有的
   ③虚方法中要有方法体,可以被子类重写,也可以不被子类重写
3)抽象方法重写
①什么是抽象方法呢?
 抽象方法:即在父类方法的修饰符后加 abstract 关键字,抽象方法没有方法体,只能存在于抽象类中。一旦子类继承了抽象类,则抽象类中的抽象方法必须在子类中重写。
②重写父类抽象方法

public class Person
{      
    public abstract void Show();       
}
public class Teacher : Person
{
    public override void Show()
    {
        Console.WriteLine("我是老师别害怕");
    }
}

★看完以上三种重写方法,有没有什么疑问呢?使用 new 关键字隐藏和使用 override 重写有什么不同呢?
 1.首先来看一下它们的定义:
  new(隐藏):子类只是把父类中的同名方法隐藏了,其实在子类中还存在父类的方法。如果需要用到父类的方法,还可以再调用父类的方法,也可以调用自己的方法。
  override(重写):子类将父类中的方法重写了,在子类中已经不存在父类的方法了,调用的时候只能调用自己的方法。
 2.什么意思呢?
  如果使用 new 关键字隐藏父类的方法,即定义的变量为父类则调用父类方法,定义的变量为子类则调用子类的方法,调用哪个方法,取决于定义的变量类型。
  如果使用 override 关键字重写父类方法,即不管定义的变量类型为父类还是子类时,但 new 的是子类对象时,皆调用子类的方法。调用哪个方法,取决于 new 的对象实例
3.下面来看一下例子

//使用 new 关键字
public class Person
{      
    public void Show()
    {
        Console.WriteLine("我是人别害怕");
    }        
}
public class Teacher : Person
{
    public new void Show()
    {
        Console.WriteLine("我是老师别害怕");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Person p = new Teacher();
        p.show();             //调用父类方法
        Teacher t = new Teacher();
        t.Show();             //调用子类自己的方法
        ((Person)t).show();   //仍然调用父类方法
    }
}

//output:
//我是人别害怕
//我是老师别害怕
//我是人别害怕

//调用父类方法还是调用子类方法,取决于定义的变量类型
//使用 override 重写父类方法
public class Person
{      
    public virtual void Show()
    {
        Console.WriteLine("我是人别害怕");
    }        
}
public class Teacher : Person
{
    public override void Show()
    {
        Console.WriteLine("我是老师别害怕");
    }
}
public class Student : Person
{
    public override void Show()
    {
        Console.WriteLine("我是学生别害怕");
    }
}
class Program
{
    static void Main(string[] args)
    {
        //下面三个变量不能同时存在,因为同名了,读者在测试的时候,可选择替换后面的对象
        Person p = new Person();
        p.show();             //调用Person类方法
        Person p = new Teacher();
        p.show();             //调用Teacher类方法
        Person p = new Student();
        p.show();             //调用Student类方法
    }
}

//output:
//我是人别害怕
//我是老师别害怕
//我是学生别害怕

//调用哪个方法,取决于 new 的对象,这也就体现了多态,即对象不同,方法相同,但是行为却不同

★虚方法和抽象方法的比较
这里写图片描述

2.接口

1)什么是接口?
接口也是多态的一种体现。接口是一种规范,它规定了能干什么,如果某一个类实现了接口,就必须实现接口中的方法。
2)接口是干什么的?
由于类继承的单根性,无法继承多个类,但是可以实现多个接口。每个接口的功能单一,这就弥补了继承的不足。
3)接口示例

interface IFly
{
    void IFly();
}
public class Teacher:Person,IFly
{
    public void IFly()
    {
        Console.WriteLine("我是老师,我会飞");
    }
}
public class Student : IFly
{
    public void IFly()
    {
        Console.WriteLine("我是学生,我也会飞");
    }
}
class Program
{
    static void Main(string[] args)
    {
        IFly ifly = new Teacher();   //多态的另一种体现
        ifly.IFly();
        IFly ifly = new Student();
        ifly.IFly();
    }
}

//output:
//我是老师,我会飞
//我是学生,我也会飞

猜你喜欢

转载自blog.csdn.net/zwj_jyzl/article/details/80628376
今日推荐