• C# 虚方法、非虚方法、重写override、new,具体调用哪个方法分析


    首先先看override和new的语法特征:

      • override
        1. override是派生类用来重写基类中方法的;
        2. override不能重写非虚方法和静态方法
        3. override只能重写用virtual、abstract、override修饰的方法;
        4. 不能使用修饰符 new、static、virtual 或 abstract 来修改 override 方法。
        new
        1. new是派生类用来隐藏基类中的方法的;也就是说在派生类中“看不到”基类中的方法;
        2. 如果要在派生类中隐藏(不是重写)基类中的方法,而没有使用new关键字,编译时会出现一个警告,提示如果是要隐藏基类中的方法,请使用new关键字【默认是new修饰的】;
        3. 派生类可以隐藏基类中的虚方法,也可以隐藏基类中的普通方法。
        4. 如果在派生类中用private来修饰new 方法,那么只在该派生类中隐藏了基类中的方法,在该派生类之外,相当于没有隐藏基类中的方法;
        5. 如果在派生类中隐藏了基类中的方法,在该派生类的派生类中,将延续对该派生类对基类方法的隐藏。

    测试结论:

    • 经测试:只有类中有虚方法重写override,才会表现出运行时类型方法特征其他无论是不是虚方法,是不是有new 修饰,是不是有override 修饰,都表现出编译时类型方法特征【即声明的类型是什么就调用什么方法】。

    以下是测试方法内容:

    //1、虚方法重写override,运行时类型方法特征。
    //1.1、虚方法未重写,编译时【未重写派生类调用基类方法】产生装箱或转型
    //1.2、虚方法重写new或没有new也没有override,编译时【重写派生类隐藏基类方法】
    //2、非虚方法重写。编译时【重写派生类隐藏基类方法】
    //3、非虚方法未重写,调用基类方法。编译时【未重写派生类调用基类方法】产生装箱或转型

     

     

     代码

     1     public class TestShape
     2     {
     3         public static void Main(string[] args)
     4         {
     5             //主要测试:1、虚方法重写override,运行时类型方法特征。
     6             //1.1、虚方法未重写,编译时【未重写派生类调用基类方法】装箱或转型
     7             //1.2、虚方法重写new或没有new也没有override,编译时【重写派生类隐藏基类方法】
     8             //2、非虚方法重写。编译时【重写派生类隐藏基类方法】
     9             //3、非虚方法未重写,调用基类方法。编译时【未重写派生类调用基类方法】装箱或转型
    10 
    11             //1、
    12             Shape shape = new Circle();
    13             shape.MethodVirtual();//circle override MethodVirtual
    14             //2、编译时
    15             Diamond diamond = new Diamond();
    16             diamond.Method();//Diamond default Method
    17             Shape s = new Diamond();
    18             s.Method();//base Method call
    19             //结论:非虚方法重写编译时 类型方法。
    20             //1.2 编译时
    21             diamond.MethodVirtual();//Diamond default MethodVirtual,没有使用override默认是new
    22             s.MethodVirtual();//base MethodVirtual call,没有使用override默认是new
    23             //3、编译时
    24             Circle circle = new Circle();
    25             circle.Method();//base Method call
    26         }
    27     }
    28     public class Shape
    29     {
    30         public virtual void MethodVirtual()
    31         {
    32             Console.WriteLine("base MethodVirtual call");
    33         }
    34         public void Method()
    35         {
    36             Console.WriteLine("base Method call");
    37         }
    38     }
    39     public class Circle: Shape
    40     {
    41         public override void MethodVirtual()
    42         {
    43             Console.WriteLine("circle override MethodVirtual");
    44         }
    45     }
    46     public class Triangle : Shape
    47     {
    48         public new  void MethodVirtual()
    49         {
    50             Console.WriteLine("Triangle new MethodVirtual");
    51         }
    52         public new void Method()
    53         {
    54             Console.WriteLine("Triangle new Method");
    55         }
    56     }
    57     public class Diamond : Shape
    58     {
    59         //默认是使用了new关键字
    60         public void MethodVirtual()
    61         {
    62             Console.WriteLine("Diamond default MethodVirtual");
    63         }
    64         public void Method()
    65         {
    66             Console.WriteLine("Diamond default Method");
    67         }
    68     }
    View Code

    语言对比

    Java——默认虚方法

    默认情况下,Java中的方法都是虚方法。假如希望方法具有非虚的行为,就必须显式密封它。相反,C#的方法默认为非虚方法

    源码,是痛苦的,又是快乐的,如果没有这痛苦,也就没有了这快乐!
  • 相关阅读:
    hive函数之~字符串函数
    hive函数之~条件函数
    JSONP使用及注意事项小结
    css命名管理混乱?不妨试试BEM
    【移动端debug-6】如何做一个App里的web调试小工具
    ES6学习笔记(五):Class和Module
    ES6学习笔记(三):与迭代相关的新东东
    ES6学习笔记(四):异步操作
    ES6学习笔记(二):引用数据类型
    CORS跨域资源共享简述
  • 原文地址:https://www.cnblogs.com/erlongxizhu-03/p/12993830.html
Copyright © 2020-2023  润新知