C# 教程 在线

2406C# 多态性

1、重载(overload): 在同一个作用域(一般指一个类)的两个或多个方法函数名相同,参数列表不同的方法叫做重载,它们有三个特点(俗称两必须一可以):

  • 方法名必须相同
  • 参数列表必须不相同
  • 返回值类型可以不相同

例如:

public void Sleep()
{
    Console.WriteLine("Animal睡觉");
}
public int Sleep(int time)
{
    Console.WriteLine("Animal{0}点睡觉", time);
    return time;
}

2、重写(override):子类中为满足自己的需要来重复定义某个方法的不同实现,需要用 override 关键字,被重写的方法必须是虚方法,用的是 virtual 关键字。它的特点是(三个相同):

  • 相同的方法名
  • 相同的参数列表
  • 相同的返回值

如:父类中的定义:

public virtual void EatFood()
{
    Console.WriteLine("Animal吃东西");
}

子类中的定义:

public override void EatFood()
{
    Console.WriteLine("Cat吃东西");
    //base.EatFood();
}

小提示:经常有童鞋问重载和重写的区别,而且网络上把这两个的区别作为 C# 做常考的面试题之一。实际上这两个概念完全没有关系,仅仅都带有一个“重”字。他们没有在一起比较的意义,仅仅分辨它们不同的定义就好了。

3、虚方法:即为基类中定义的允许在派生类中重写的方法,使用virtual关键字定义。如:

public virtual void EatFood()
{
    Console.WriteLine("Animal吃东西");
}

注意:虚方法也可以被直接调用。如:

Animal a = new Animal();
a.EatFood();

执行输出结果为:

Animal吃东西

4、抽象方法:在基类中定义的并且必须在派生类中重写的方法,使用 abstract 关键字定义。如:

public abstract class Biology
{
    public abstract void Live();
}
public class Animal : Biology
{
    public override void Live()
    {
        Console.WriteLine("Animal重写的抽象方法");
        //throw new NotImplementedException();
    } 
}

注意:抽象方法只能在抽象类中定义,如果不在抽象类中定义,则会报出如下错误:

虚方法和抽象方法的区别是:因为抽象类无法实例化,所以抽象方法没有办法被调用,也就是说抽象方法永远不可能被实现。

5、隐藏方法:在派生类中定义的和基类中的某个方法同名的方法,使用 new 关键字定义。如在基类 Animal 中有一方法 Sleep():

public void Sleep()
{
    Console.WriteLine("Animal Sleep");
}

则在派生类 Cat 中定义隐藏方法的代码为:

new public void Sleep()
{
    Console.WriteLine("Cat Sleep");
}

或者为:

public new void Sleep()
{
    Console.WriteLine("Cat Sleep");
} 

注意:

  • (1)隐藏方法不但可以隐藏基类中的虚方法,而且也可以隐藏基类中的非虚方法。
  • (2)隐藏方法中父类的实例调用父类的方法,子类的实例调用子类的方法。
  • (3)和上一条对比:重写方法中子类的变量调用子类重写的方法,父类的变量要看这个父类引用的是子类的实例还是本身的实例,如果引用的是父类的实例那么调用基类的方法,如果引用的是派生类的实例则调用派生类的方法。

更多内容可参考: C# 中的多态性

2405C# 多态性

抽象方法和虚方法的区别

  • 1.虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
  • 2.抽象方法只能在抽象类中声明,虚方法不是。如果类包含抽象方法,那么该类也是抽象的,也必须声明类是抽象的。
  • 3.抽象方法必须在派生类中重写,这一点和接口类似,虚方法不需要再派生类中重写。

简单说,抽象方法是需要子类去实现的。虚方法是已经实现了的,可以被子类覆盖,也可以不覆盖,取决于需求。

抽象方法和虚方法都可以供派生类重写。

2404C# 多态性

virtual 和 abstract

virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义。

  • 1.virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不能实现。
  • 2.virtual可以被子类重写,而abstract必须被子类重写。
  • 3.如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法。
  • 4.无法创建abstract类的实例,只能被继承无法实例化。

重载和重写

重载(overload)是提供了一种机制, 相同函数名通过不同的返回值类型以及参数来表来区分的机制。

见:函数重载

重写(override)是用于重写基类的虚方法,这样在派生类中提供一个新的方法。

见:动态多态性

2403C# 多态性

C# 多态性

多态:一个接口多个功能。

静态多态性:编译时发生函数响应(调用);

动态多态性:运行时发生函数响应。

静态绑定(早期绑定):编译时函数和对象的连接机制。两种技术实现静态多态性:函数重载/运算符重载。

函数重载:在同一范围内对相同函数名有多个定义,可以是参数类型或参数个数的不同,但不许只有返回值类型不同。

运算符重载:

关键字 abstract 声明抽象类:用于接口部分类的实现(派生类继承抽象类时,实现完成)。抽象类包含抽象方法,抽象方法可被派生类实现。

抽象类规则:

  • 1.不能创建抽象类的实例
  • 2.不能在抽象类外定义抽象方法
  • 3.不能把抽象类声明为sealed(类前带关键字sealed代表该类是密封类,不能被继承)

关键字virtual声明虚方法:用于方法在继承类中的实现(在不同的继承类中有不同的实现)。

抽象类和虚方法共同实现动态多态性。

注:继承类中的重写虚函数需要声明关键字 override,在方法参数传入中写(类名 形参名)例如 public void CallArea(Shape sh),意思是传入一个 shape 类型的类。

2402C# 继承

创建子类对象调用子类的构造函数时,会首先调用父类的无参构造函数。

using System;

namespace ConsoleApp1
{
    class Program
    {
        class father
        {
            public father()
            {
                Console.WriteLine("father");
            }
        }
        class son : father
        {
            public son()
            {
                Console.WriteLine("son");
            }
        }
        static void Main(string[] args)
        {
            son s = new son();
            Console.ReadKey();
        }
    }
}

输出结果:

father
son