zoukankan      html  css  js  c++  java
  • 虚方法

    using System;
     
    class A {
        public void F() { Console.WriteLine("A.F"); }
        public virtual void G() { Console.WriteLine("A.G"); }
    }
    class B : A {
        new public void F() { Console.WriteLine("B.F"); }
        public override void G() { Console.WriteLine("B.G"); }
    }
    class Test {
        static void Main() {
            B b = new B();
            A a = b;
            a.F();
            b.F();
            a.G();
            b.G();
        }
    }

      这是今天看书的一段代码,mark!

      在该示例中,A 引入一个非虚方法 F 和一个虚方法 G。类 B 引入一个新的非虚方法 F,从而隐藏了继承的 F,并且还重写了继承的方法 G。根据对象初始化的过程,着眼于方法表的顺序:关注对象,从自身类向派生类搜索到第一个可以访问的同名方法。“在虚方法调用中,该调用所涉及的那个实例的运行时类型 (run-time type) 确定了要被调用的究竟是该方法的哪一个实现。在非虚方法调用中,相关的实例的编译时类型 (compile-time type) 是决定性因素。”(——《C#规范4.0》)由此可知,实例a b内存的布局前半部分是一致的,运行时类型b:B.F B.G 。编译类型a:A.F A.G B.G B.F  ,然后根据名称找方法,分别是 A.F B.F B.G B.G。

      对调用哪个实际方法实现起决定作用的是该实例的运行时类型(即引用类型 A),而不是该实例的编译时类型(即实际内存分配对象B)。

    class A {
        public virtual void F() { Console.WriteLine("A.F"); }
    }
    class B : A {
        public override void F() { Console.WriteLine("B.F"); }
    }
    class C : B {
        new public virtual void F() { Console.WriteLine("C.F"); }
    }
    class D : C {
        public override void F() { Console.WriteLine("D.F"); }
    }
    class Test {
        static void Main() {
            D d = new D();
            A a = d;
            B b = d;
            C c = d;
            a.F();
            b.F();
            c.F();
            d.F();
        }
    }

      C 类和 D 类包含两个具有相同签名的虚方法:一个是 A 引入的,另一个是 C 引入的。但是,由 C 引入的方法隐藏了从 A 继承的方法。因此,D 中的重写声明所重写的是由 C 引入的方法,D 不可能重写由 A 引入的方法。内存都D的布局,a.F搜索到B类有满足方法,b.F也是直接该类满足,c和d同理。此例产生输出:B.F B.F D.F D.F。

  • 相关阅读:
    Springboot整合Dubbo
    网站appache的ab命令压力测试性能
    静态页面框架
    CSS布局设计
    弹性盒子的总结
    弹性盒子
    应用媒介查询制作响应式导航栏
    响应式的设计需要遵守的4个原则和媒介查询语句
    media type的类型汇总
    background-orgin属性
  • 原文地址:https://www.cnblogs.com/lijinfeng042/p/2227686.html
Copyright © 2011-2022 走看看