zoukankan      html  css  js  c++  java
  • 虚方法和重写方法的继承特性

          这个题目起的还是有点不合适,但是当你看到下面的代码就会明白我在搞些什么名堂,其实质是辨析了一下virtual关键字和override关键字,MD写的代码,部分语言输入法兼容性问题,搞的我只能用用英文注释,破键盘这两也让我敲坏了很多键都按下了不起作用了,无奈啊。。。。下面我按我的理解简单的介绍一下虚方法和重写方法。       


    虚方法这个方法其实就是为了重写方法而存在的(在声明中包含virtual关键字),否则哪,我也没感觉它存在的意义。

    其一:因为要重写所以它的访问类型如果为private则毫无意义阻碍了重写动作的进行也就是它不能私有化,所以C#中virtual关键字和private关键字不能同时使用。

    其二:因为静态的方法和抽象方法不能重写,同理C#中static,abstract关键字和virtual关键字不能同时使用。

    其三:不能在声明虚方法的同时指定重写虚方法,因为重写方法只能重写基类的虚方法,也就是要提前在基类中声明虚方法,所以virtual关键字和override关键字不能同时使用。

    重写方法就是使从基类继承的虚方法提供新的实现(使用关键字override声明),从而为其子类所专有化。

    同上面的思路一样:因为静态的方法和抽象方法不能重写,同理C#中static,abstract,new关键字和override关键字不能同时使用。


    今天彻底的实验了一下,总结用法如下:

    非虚方法的实现(全部隐藏的虚方法)最初声明的是什么类的方法就永远是什么类的方法。

    虚方法的实现:最终是什么类型的方法就调用该类型的方法。

    (含有隐藏的)虚方法的实现:最终是什么类型的方法就调用(最靠近)该类型的方法。


     直接上代码,看看就明白了我总结的用法了。


     using System;

    namespace HideTest
    {
        class Great_grandfather
        {
            public void printf()
            {
                Console.WriteLine("曾祖父.printf()");
            }//非虚方法
            public virtual void F()
            {
              Console.WriteLine("曾祖父.F()");
            }//虚方法
            public virtual void D()
            {
                Console.WriteLine("曾祖父.D()");
            }//虚方法
            public virtual void E()
            {
                Console.WriteLine("曾祖父.E()");
            }
        }

        class grandfather:Great_grandfather
        {
            new private void printf() //仅在grandfather类内隐藏Great_grandfather.printf()方法
            {
                Console.WriteLine("祖父.printf()");
            }
            public void Show()
            {
              grandfather n=new grandfather();
              n.printf();
            }
             new public virtual void F()
            {
                Console.WriteLine("祖父.F()");
            }
             public override void D()
             {
                 Console.WriteLine("祖父.D()");
             }
             public override void E()
             {
                 Console.WriteLine("祖父.E()");
             }
        }
        class father_1:grandfather
        {
            new public void printf()
            {
                Console.WriteLine("父.printf()");
            }
            new public virtual void F()
            {
                Console.WriteLine("父.F()");
            }
            new public virtual void D()//Hide The base class methods, Redefined a new method.
            {
                Console.WriteLine("父.D()");
            }
            public override void E()
            {
                Console.WriteLine("父.E()");
            }
        }
        class father_2 : grandfather
        {
            public void TryHide()
            {
                father_2 father = new father_2();
                father.printf();
            }
        }
        class child:father_1
        {
            new public void printf()
            {
                Console.WriteLine("子.printf()");
            }
            new public virtual void F()
            {
                Console.WriteLine("子.F()");
            }
            public override void D()
            {
                Console.WriteLine("子.D()");
            }
            public override void E()
            {
                Console.WriteLine("子.E()");
            }
          }
        class Test
        {
            public static void Main()
            {
                child a = new child();
                father_1 b = a;
                grandfather c = a;
                Great_grandfather d = a;
                father_2 e = new father_2();
                Console.WriteLine("=========test the inherited of methods===========\n\n");
                Console.WriteLine("=========测试隐藏非虚方法===========");
                a.printf();  //调用child.printf(),打印子.printf()
                b.printf();  //调用father.printf(),打印父.printf()
                e.printf();  //此处证明仅在grandfather类内隐藏了Great_grandfather.printf()方法
                             //所以此处仍调用Great_grandfather.printf()
                c.printf(); //因为father.printf()在grandfather类外不可见( 注意和e.printf()的区别)
                            //所以仍调用继承的Great_grandfather.printf()的方法
                c.Show();   //在grandfather类内隐藏了Great_grandfather.printf()的方法在打印祖父.printf()
                d.printf();//调用 Great_grandfather.printf()打印曾祖父.printf()
                Console.WriteLine("=========测试(隐藏的)隐藏虚方法===========");
                a.F();//调用Child.F()
                b.F();//调用father.F()
                c.F();//调用grandfather.F()
                d.F();//调用Great_grandfather.F()
                Console.WriteLine("=========测试重写(含隐藏的)虚方法===========");
                a.D();//调用Child.D()
                b.D();//调用Child.D()          override by the Chid.D()
                c.D();//调用grandfather.D()    because it is Hide in the (farther)class not override 
                d.D();//调用grandfather.D()    override by the grandfather.D() 
                Console.WriteLine("=========测试重写(不含隐藏的)虚方法===========");
                a.E();//调用Child.E()
                b.E();//调用Child.E()
                c.E();//调用Child.E()
                d.E();//调用Child.E()
                Console.WriteLine("=========OVER===========");
                Console.ReadKey();
            }
        }
    }

  • 相关阅读:
    Why Choose Jetty?
    Jetty 的工作原理以及与 Tomcat 的比较
    Tomcat设计模式
    Servlet 工作原理解析
    Tomcat 系统架构
    spring boot 打包方式 spring boot 整合mybaits REST services
    wireshark udp 序列号 User Datagram Protocol UDP
    Maven 的聚合(多模块)和 Parent 继承
    缓存策略 半自动化就是mybaitis只支持数据库查出的数据映射到pojo类上,而实体到数据库的映射需要自己编写sql语句实现,相较于hibernate这种完全自动化的框架我更喜欢mybatis
    Mybatis解决sql中like通配符模糊匹配 构造方法覆盖 mybits 增删改
  • 原文地址:https://www.cnblogs.com/rohelm/p/2384118.html
Copyright © 2011-2022 走看看