编程语言
首页 > 编程语言> > C#易错易混淆知识总结(七)--{多态}{抽象类于抽象方法}

C#易错易混淆知识总结(七)--{多态}{抽象类于抽象方法}

作者:互联网

一 多态

里氏替换原则就已经说明了多态的精髓“子类对象可以替换父类对象的位置,而程序的功能不受影响”。

      class Person
    {
       
       //定义虚方法以备子类重写,当子类替换父类对象的位置时,可以表现出多态
        public virtual void Run()
        {
            Console.WriteLine("我是人,我会跑!");
        }

        public virtual void Say()
        {
            Console.WriteLine("我是人,我会说话!");
        }
    }

//定义Teacher类继承Person
class Teacher:Person
{
public override void Run()
{
Console.WriteLine("我是老师,我必须慢速跑");
}


public override void Say()
{
Console.WriteLine("我是老师,我得说表扬的话!");
}


}


//定义Student类继承Person
class Student : Person
{
//子类重写了父类的虚方法
public override void Run()
{
Console.WriteLine("我是学生,我会加速跑!");
}


public override void Say()
{
Console.WriteLine("我是学生,我会说英语!");
}
}

//实现多态的类
class FeatureHuman
{
/// <summary>
/// 这个方法就提现了多态,当传入的是子类的对象的时候,p指向的是子类对象,就可以调用子类重写父类方法后的方法
/// </summary>
/// <param name="p">父类或者子类对象</param>
public void OutPutFeature(Person p)
{
p.Run();
p.Say();
}
}

 

主体代码和实现多态的方法如下:

static void Main(string[] args)
        {
            FeatureHuman fea = new FeatureHuman();
            //人的特点
            Person p = new Person();

            Program pro = new Program();
            fea.OutPutFeature(p);

            //学生的特点
            Student s = new Student();
            fea.OutPutFeature(s);
            //老师的特点
            Teacher t = new Teacher();
            fea.OutPutFeature(t);

            Console.ReadKey();
        }

运行,打印结果如下:

 

 这里可以发现,我们outputFeature方法根据传入的实体对象不同(父类变量指向了子类的对象),而打印出了不同人物的特点,这就是多态。

多态总结如下:

 

 二,抽象类和抽象方法

在C#中使用abstract关键字修饰的类和方法,叫做抽象类和抽象方法。

1)抽象类中可以拥有没抽象成员,为了继承给他的子类调用 (抽象类就是为了定义抽象成员,继承给子类去实现,同时子类也可以调用父类的非抽象成员)

abstract  class Person
    {
       //private int nAge;

       //abstract string strName;

       //抽象类可以包含不抽象的成员,可以给继承的子类使用
       public void Say()
       {
           Console.WriteLine("我是父类,我是人!");
       }

       public virtual void Sing()
       {
           Console.WriteLine("我是父类,我是人,我可以唱歌!");
       }

       //Run的抽象方法
       public abstract void Run();
    }

2)抽象类中可以有virtual修饰的虚方法

如上面的代码,在抽象类中定义了virtual修饰的方法,编译通过。抽象类就是为了定义抽象成员,继承给子类去实现,所以子类也可以实现抽象类中的虚方法。

3)抽象类不能实例化,因为有抽象成员,而抽象成员没有方法体,如下图,

4)抽象成员不能私有,如果私有子类没有办法访问 

我们可以在抽象类中定义私有成员,但是没有意义。因为子类根本访问不到这些私有成员,而抽象类本身也不能实例化,所以私有成员访问不到。

5)子类必须重写父类的抽象方法 

在上面代码的基础上,我们定义一个Student类,继承抽象类,但是不实现抽象类的抽象方法,编译报错。代码如下:

 6)在子类中没有办法通过base关键字调用父类抽象方法 

原理同上,抽象类的抽象发放没有实现语句,就算调用也没有意义。但是可以使用base关键字调用非抽象方法,代码如下:

class Program
    {
        static void Main(string[] args)
        {
            //Person p = new Person();
            Student s = new Student();
            s.Run();
            Console.ReadLine();
        }
    }

    class Student : Person
    {
       
        public override void Run()
        { 
            base.Say();
            Console.WriteLine("我是学生,继承了父类,我可以跑!");
        }
    }

总结如下:

 

抽象方法:

1)抽象方法必须定义在抽象类中,

2)抽象方法必须使用关键字修饰,示例代码如下:

abstract class Person
    {
        //private int nAge;

        //abstract string strName;

        //抽象类可以包含不抽象的成员,可以给继承的子类使用
        public void Say()
        {
            Console.WriteLine("我是父类,我是人!");
        }

        public virtual void Sing()
        {
            Console.WriteLine("我是父类,我是人,我可以唱歌!");
        }

        //Run的抽象方法,不能有方法体,留给子类实现
        public abstract void Run();

 

那么什么时候使用抽象类呢?

①子类必须重写父类的方法(相当于定义了一个标准,规范)

②父类没有必要实例化,就用抽象类

③抽象类是为了继承,为了多态

 

标签:易错,C#,子类,void,多态,抽象,抽象类,父类,public
来源: https://www.cnblogs.com/JingHaoYu/p/16104983.html