C#的继承&多态

继承

  1. 继承(以及封装和多态性)是面向对象的编程的三个主要特征之一。
    通过继承,可以创建新类,以便重用、扩展和修改在其他类中定义的行为。
    其成员被继承的类称为“基类”,继承这些成员的类称为“派生类”。
  2. 派生类只能有一个直接基类。
  3. 但是,继承是可传递的。
    如果 ClassC 派生自 ClassB,并且 ClassB 派生自 ClassA,则 ClassC 将继承在 ClassB 和 ClassA 中声明的成员。
// 基类
class Person
    {
        public string name;
        public int age;

        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }

        public void read()
        {
            Console.WriteLine("Person can read.");
        }
    }
    
// 派生类
class Student: Person
    {
        public int id;
        public Student(string name, int age, int id) : base(name, age) // 如果基类的构造函数没有参数,则派生类的构造函数不需要使用base.
        {
            this.id = id;
        }

        public new void read() // 这里也可以不写 “new”, 但是VS会发出警告
        {
            Console.WriteLine("Student can read.");
        }

        public void study()
        {
            base.read();
            Console.WriteLine("Then can study.");
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student("joe", 20, 114);
            stu.study();
        }

    }

// 运行结果:
Person can read.
Then can study.

多态

  1. Hide base class members with new members
    – 如果希望派生类具有与基类中的成员同名的成员,则可以使用 new 关键字隐藏基类成员;
    new关键字可加可不加,但不加的话,VS会发出警告;
    – 在派生类的方法上使用new关键字时,不需要在基类做任何改动,就像上面的例子所示;
    – 通过将派生类的实例强制转换为基类的实例,可以访问隐藏的基类成员,如下例:
Student B = new Student(...);
B.read();  // Calls the new method.
// Student can read.

Person A = (Student)B;
A.read();  // Calls the old method.
// Person can read.
  1. Virtual members
    – 仅当基类成员声明为 virtualabstract 时,派生类才能重写基类成员;
    – 派生成员必须使用 override 关键字显式指示该方法将参与虚调用。
    – 当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员,如下所示:
Student B = new Student("joe", 20, 114);
B.read();  // Calls the new method.
// Student can read.

Person A = (Person)B;
A.read();  // Also calls the new method.
// Student can read.
  • Hide base class members with new members
    – 无论在虚拟成员和最初声明虚拟成员的类之间已声明了多少个类,虚拟成员都是虚拟的。 如果类 A 声明了一个虚拟成员,类 B 从 A 派生,类 C 从类 B 派生,则不管类 B 是否为虚拟成员声明了重写,类 C 都会继承该虚拟成员,并可以重写它。
  • Access base class virtual members from derived classes
    – 已替换或重写某个方法或属性的派生类仍然可以使用 base 关键字访问基类的该方法或属性,如上例中的study方法。

替换(new)与重写(override)

在 C# 中,派生类可以通过关键字newoverride包含与基类方法同名的方法。

  • 如果派生类中的方法前面没有 newoverride 关键字,则编译器将发出警告,该方法将如同存在 new 关键字一样执行操作;
  • 如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法;
  • 如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不是调用基类方法;
  • 若要将 override 关键字应用于派生类中的方法,必须以虚拟形式(virtualabstract)定义基类方法;
  • overridevirtualnew 关键字可以用于方法、属性、索引器(indexer)和事件中。

virtual 与 abstract

virtual 关键字

  • 可用于修饰方法,属性,索引器和事件;
  • 被修饰的方法有其自己的实现;
  • 在派生类中可以重写virtual方法的实现;
  • 不能和static, abstract, private和override修饰符同时使用。

abstract 关键字

  • 可用于修饰类, 方法, 属性, 索引器和事件;
  • The abstract modifier indicates that the thing being modified has a missing or incomplete implementation;
    (对于方法来说和属性,没有具体实现;
    对类来说,类中有些方法没有被实现或这整个类都没有具体实现。
    所以如果一个类中有成员是抽象的,则其一定是抽象类;但一个抽象类中不一定有抽象的成员)

抽象类

  • 不能被实例化,只能作为其他类的基类;
  • 类中可以包含抽象和非抽象成员;
  • 不能同时使用sealed关键字修饰该类;
  • 派生自抽象类的类必须实现该抽象类所有的非私有成员;
  • 如果抽象类实现了某个接口,则它必须实现接口中的所有成员。

抽象方法

  • 抽象方法即是隐式的虚拟方法(virtual),之后在具体实现时要用override关键词修饰;
  • 抽象方法只存在与抽象类中;
  • 抽线和方法没有具体实现,所以没有花括号和函数体,直接以分号结尾,例如:
public abstract void MyMethod();

抽象属性

  • 不能与static或virtual关键字同时使用;
  • An abstract inherited property can be overridden in a derived class by including a property declaration that uses the override modifier;
  • 其余和抽象方法类似。

参考资料

Polymorphism (C# Programming Guide)
Versioning with the Override and New Keywords (C# Programming Guide)
virtual (C# Reference)
abstract (C# Reference)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值