CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Java >  J2SE / 基础类

C#、C++和Java中重载和覆盖的一点问题

楼主dx20()2006-03-12 14:49:35 在 Java / J2SE / 基础类 提问

废话少说,先看一个简单的C++程序:  
  #include   <iostream>  
  using   namespace   std;  
   
  class   myFirst  
  {  
          public:  
                  void   funcA()  
                  {  
                          cout<<"这是myFirst类的非虚拟函数\n";  
                  }          
                  virtual   void   funcB()  
                  {  
                          cout<<"这是myFirst类的虚拟函数\n";  
                  }  
  };        
  class   mySecond   :   public   myFirst  
  {  
          public:  
                  void   funcA()  
                  {  
                          cout<<"这是mySecond类的非虚拟函数\n";  
                  }          
                  virtual   void   funcB()  
                  {  
                          cout<<"这是mySecond类的虚拟函数\n";  
                  }  
  };            
   
  int   main()  
  {  
          mySecond   bb;  
          ①     bb.funcA();  
          ②     bb.funcB();  
          ③     ((myFirst*)(&bb))->funcA();  
          ④     ((myFirst*)(&bb))->funcB();  
          ⑤     ((myFirst)(bb)).funcA();  
          ⑥     ((myFirst)(bb)).funcB();  
          return   0;    
  }  
  1和2的输出就不说了,很明确;5和6是向上强制转型(upcasting),将会造成对象的内容被切割;小弟不明白3和4的输出,主要就是(myFirst*)(&bb)这个表达式(我理解是把bb的地址形式转换为myFirst的地址形式),这个表达式对bb的内容有什么样的影响,对于输出的原因不太清楚,烦请各位高手解答一下,最好能从本质上解释。整个程序的输出结果如下所示:  
   
  这是mySecond类的非虚拟函数  
  这是mySecond类的虚拟函数  
  这是myFirst类的非虚拟函数  
  这是mySecond类的虚拟函数  
  这是myFirst类的非虚拟函数  
  这是myFirst类的虚拟函数  
  ******************************************    
   
  下面是同样内容的C#程序:  
  using   System;  
  using   System.Collections.Generic;  
  using   System.Text;  
   
  namespace   虚函数测试Cs  
  {  
        public   class   myFirst  
        {  
              public   void   funcA()  
                  {  
                          Console.WriteLine("这是myFirst类的非虚拟函数");  
                  }          
              public   virtual   void   funcB()  
                  {  
                          Console.WriteLine("这是myFirst类的虚拟函数");  
                  }  
        };        
      public   class   mySecond   :   myFirst  
      {  
              new   public   void   funcA()  
                  {  
                          Console.WriteLine("这是mySecond类的非虚拟函数");  
                  }          
              public   override   void   funcB()  
                  {  
                          Console.WriteLine("这是mySecond类的虚拟函数");  
                  }  
      };  
  class   Program  
          {  
                  static   void   Main(string[]   args)  
                  {  
                          mySecond   bb   =   new   mySecond();  
                          ①   bb.funcA();  
                          ②   bb.funcB();  
                          ③   ((myFirst)(bb)).funcA();  
                          ④   ((myFirst)(bb)).funcB();  
                    }  
          }  
  }  
  1和2的输出很明确,不说了。  
  C#   和C++在类对象赋值运算符(=)这个地方不一样,C++是对象的复制,而在C#中,”=”复制它的引用,即地址,而不是复制对象。例如有一个类A   ,在C++中,   代码A   a;A   b=a;是生成了两个类对象a和b,且这两个对象里面的数据成员的值应该是一样的,而在C#中,代码   A   a   =   new   A();A   b=a;运行之后,b和a其实指向的地址是同样的,b只是a的一个引用。所以从这个角度来讲,我觉得在C#中,(myFirst)(bb)应该和C++中的(myFirst*)(&bb)在本质上是一样的,经验证,本程序中的3和4与C++程序中的3和4的输出结果是统一的。  
  本程序输出如下:  
  这是mySecond类的非虚拟函数  
  这是mySecond类的虚拟函数  
  这是myFirst类的非虚拟函数  
  这是mySecond类的虚拟函数  
  **********************************************  
     
  下面是同样内容的Java程序:  
  class   myFirst  
  {  
          public   void   funcA()  
                  {  
                          System.out.println("这是myFirst类的非虚拟函数");  
                  }          
  }      
  class   mySecond   extends   myFirst  
  {  
          public   void   funcA()  
                  {  
                  System.out.println("这是mySecond类的非虚拟函数");      
          }          
  }  
   
  public   class   test   {  
  public   static   void   main(String[]   args)   {  
  mySecond   bb=new   mySecond();  
  ①   bb.funcA();  
  ②   ((myFirst)bb).funcA();  
  }  
  }  
  由于Java中没有虚拟函数,所以只能测试一下函数覆盖的情况。Java和C#类似,”=”复制类对象之间的地址,我原本以为1和2的输出应该和C#程序中的3和4的输出统一,不过结果却出乎我的意料,程序的输出如下:  
  这是myFirst类的非虚拟函数  
  这是myFirst类的非虚拟函数  
     
  所以小弟的第二个问题是这个Java程序这样输出的原因。另外,我刚刚学Java,看代码看的不是很多,但似乎没有见到Java中有(myFirst)bb这样的用法,是不是Java把C++中一切可能导致歧义的用法都抛弃不用了?呵呵,纯属瞎想,还请高手指出真正的原因。  
  问题点数:30、回复次数:3Top

1 楼Loveflys()回复于 2006-03-12 15:19:15 得分 0

怎么可能呢?java子类不覆盖父类的吗?Top

2 楼wangjinwang(王者之疯)回复于 2006-03-12 15:26:59 得分 30

1   在C++中,什么类型的对象,调用对应类型的(非虚拟)方法,在代码中表现为  
  ③     ((myFirst*)(&bb))->funcA();  
  输出:这是myFirst类的非虚拟函数  
   
  在C++中,虚函数的特点就是:基类指针自识别调用子类的方法,也就是对异构容器的支持,在代码中表现为  
  ④   ((myFirst)(bb)).funcB();  
  输出:这是mySecond类的虚拟函数  
   
  2   我的测试结果与你的不同,不敢分析了  
  输出为:  
  这是mySecond类的非虚拟函数  
  这是mySecond类的非虚拟函数  
  代码如下:  
  public   class   Simple   {  
  public   static   void   main(String[]   args)   {  
  try   {  
  //   Add   to   here  
  Simple   s   =   new   Simple();  
  }   catch   (Exception   e)   {  
  e.printStackTrace();  
  }  
          }  
  public   Simple()  
  {  
  mySecond   bb=new   mySecond();  
  bb.funcA();  
  ((myFirst)bb).funcA();  
  }  
  class   myFirst  
  {  
          public   void   funcA()  
                  {  
                          System.out.println("这是myFirst类的非虚拟函数");  
                  }          
  }      
  class   mySecond   extends   myFirst  
  {  
          public   void   funcA()  
                  {  
                  System.out.println("这是mySecond类的非虚拟函数");      
          }          
  }  
  }  
  Top

3 楼dx20()回复于 2006-03-12 22:37:25 得分 0

wangjinwang(王进)   不好意思   Java的那个程序的输出我写错了,你的输出时对的。请你继续分析   :)Top

相关问题

  • C#、C++和Java中重载和覆盖的一点问题
  • C++重载问题
  • C++的重载问题
  • c++ 输出符的重载??
  • 重载和覆盖的好处
  • 多态 重载 重写 覆盖??
  • 虚函数 重载 覆盖 的问题。
  • 关于C++模板重载问题
  • 在Dev-C++重载运算符问题
  • C++为什么不这样重载>>

关键词

  • c#
  • c++
  • 函数
  • 虚拟
  • java
  • 代码
  • 内容
  • myfirst
  • mysecond
  • 虚拟函数

得分解答快速导航

  • 帖主:dx20
  • wangjinwang

相关链接

  • CSDN Java频道
  • Java类图书
  • Java类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo