【心得体会】c#与java继承的时候,对方法覆盖的不同处理

      一直在博客园潜水,每天都这里看网友们写的随笔,受益匪浅!这次我第一次在网上发表文章,请大家多多关照啊!在课程上能学到东西太少,为了以后能找个好工作,一直在加深对基础知识的理解。c#和java一起巩固,毕竟两种语言的语法区别不大。最近我碰到一个问题,一直没想通,请大家来看看。文章中难免出现一些错误,或者一些地方用语不规范,请善意提醒。
      关于继承时候的方法覆盖。java与c#中结果不一样,非常疑惑。下面两段代码功能都是一样的,基类是Sharp,派生类Circle。主要的疑问是继承的时候,发生方法覆盖,处理结果不一样。
      语句1没有什么疑问,实现多态机制。c#中要virtual和override来实现,java中同名函数声明为包访问权限实现。输出:this Circle
      问题在于语句2,c#输出:形状删除,java输出:圆形删除
      同是声明一个基类对象指向派生类引用,因为函数签名相同,派生类的方法5会隐藏基类的方法4。但是c#中输出的是:形状删除,实际并没有隐藏基类的方法4,而在java中输出的是:圆形删除。
      语句3,都是输出:圆形删除。因为派生类的方法隐藏了基类的方法。
      是不是因为编译器处理方式不一样而导致的?具体为什么会这样,我也不清楚。
   (注:操作系统是xp sp2,vs2005,eclipse3.0+jdk1.5)

摘自Java编程思想后期绑定:在运行时根据对象的类型进行绑定。在运行时能判断对象的类型,从而调用恰当的方法。也就是说编译器一直不知道对象的类型,但是方法调用机制能找到正确的方法体,并加以调用。
      我的理解是:编译的时候,编译器会维护一个方法列表,存在某种机制,当声明为重写方法的时候,编译器会记录你用那个方法来重写,这样在运行的时候,便可以调用正确的方法。而当你没有声明为重写方法,即语句4和5,而出现方法隐藏的时候,编译器处理的方法不一样。如果是这样,那么在C#中,为什么语句2和语句3的结果不一样呢?C#中有提到可以用一个new关键字来显示声明要一个隐藏方法,我在这里没有声明,那就是隐式隐藏了。
      我认为这应该是编译器处理的方式不一样。虽然编译器负责词法,语法,语义分析,java中生成java字节码,c#生成IL代码。运行的时候分别由JRE和CLR来解析。可能是编译器生成的代码方法不一样吧,个人看法,可能存在错误。
namespace duotaitest
{
    
class Sharp
    
{
        
public virtual void Writer() { Console.WriteLine("this sharp"); }
        
public void Delete() { Console.WriteLine("形状删除"); }//4
    }

    
class Circle : Sharp
    
{
        
public override void Writer(){ Console.WriteLine("this Circle"); }
        
public void Delete() { Console.WriteLine("圆形删除"); } //5
    }

    
class Program
    
{
        
static void Main(string[] args)
        
{
            Sharp a 
= new Circle(); 
            a.Writer();
//1
            Sharp b = new Circle();
            b.Delete();
//2  输出:形状删除
            Circle c = new Circle();
            c.Delete();
//3  输出:圆形删除
        }

    }

}


package ploytest;
class Sharp
{
    
void Writer() { System.out.println("this sharp"); }
    
public void Delete() { System.out.println("形状删除"); }//4
}

class Circle extends Sharp
{
    
void Writer() { System.out.println("this Circle"); }
    
public void Delete() { System.out.println("圆形删除"); } //5
}

public class Program
{
   
public static void main(String[] args)
    
{
        Sharp a 
= new Circle();
        a.Writer();
//1
        Sharp b = new Circle();
        b.Delete();
//2 输出:圆形删除
        Circle c = new Circle();
        c.Delete();
//3 输出:圆形删除
    }

}
     不管怎么样,我自己总结一条经验:如果不是为了要重写方法,避免在基类和派生类中使用同名函数。
     在学习的过程中,我也有一些心得体会。我觉得一门语言的语法是很容易学的,难的是怎么用这么语言去处理问题。就好比就语法来讲,c#和java没多大区别。而就开发平台来讲还是有很大区别的,我觉得这也是因为各公司的发展策略不一样。MS目标就是推广它的产品,它的产品就是很容易入门,当我第一次在VS2005中随便拖几个控件便完成了数据库的操作以及分页,而且看起来效果还不错,还以为.NET很简单,随着学习的深入接触到ADO.NET才发现其实没那么简单,到后来接触到三层结构,什么数据层持久化更是一头雾水。
      如今开始看些java方面的书,突然发现原来他们很像,java中struts类似.net的控件啊,java的web服务器是有很多选择的啊,而且很多选择配置,而IIS帮你打理一切,等等之类的。我个人认为java和.net之间可以互相借鉴的。
      直到最近才开始明白,需要学习的是思想,学习怎么去解决的方法。又把平时经常翘课的课程拿回来重新学习,比如操作系统和编译原理。也请各位过来人,传授一些武功秘笈,我也想成为大内高手。

posted on 2008-02-02 16:15  海之魂  阅读(2216)  评论(13)    收藏  举报

导航