zoukankan      html  css  js  c++  java
  • c#,java比较

    很多人说C#是微软用来和Java抗衡的武器,因为二者在很大程度上有着惊人的相似,尽管如此,两者不同的地方也很多,所谓“于细微处见差异”。那么两者的相似和区别都在什么地方呢?我们从今天开始,会从各个角度来对比C#和Java的特点,希望能对正在学习、使用C#的朋友有所帮助。

    1、C#和.NET平台的概貌

      2000年6月,微软发布C#语言和.NET平台。C#语言是一种强类型的,面向对象的语言,它具有语法简单、表达力强的特点,而.NET平台则是构成微软的“.NET计划”的基石。

      .NET平台的核心包括两方面,一方面就是著名的通用语言运行机(Common Language Runtime),虽然这个名词起得晦涩了点,不过大家可以拿它和Java的虚拟机来作比较,二者完成的任务大致相同;另一方面就是一大堆通用函数库,这些库函数可以被多种语言调用,并且通过编译都产生一种共同的中间语言(Intermediate Language),这种语言也可以拿Java的字节码来类比,虽然完成的方式有些不一样。

    2、C#和Java

      下面简单地把C#和Java的相似处列出来,虽然在这里我们重点讨论的是C#和Java的不同点,但是了解一下二者的相同之处也是很有必要的。

      二者都编译成跨平台的、跨语言的代码,并且代码只能在一个受控制的环境中运行

      自动回收垃圾内存,并且消除了指针(在C#中可以使用指针,不过必须注明unsafe关键字)

      都不需要头文件,所有的代码都被“包(package)”限制在某个范围内,并且因为没有头文件,所以消除了类定义的循环依赖

      所有的类都是从对象派生出来,并且必须使用New关键字分配内存

      用对象加锁的方式来支持多线程

      都具有接口(interface)的概念

    内部类

      继承类的时候不会以某种特定的访问权限来继承;

      没有全局函数或者常量,一切必须属于类;

      数组或者字符串都自带长度计算和边界检查;

      只使用“.”操作符,没有“->”和“::”;

      “null”、“boolean”和“bool”成为了关键字;

      任何变量均在使用前进行初始化;

      不能使用整数来返回到if条件语句中,必须使用布尔值;

      “Try”模块后可以有“finally” ;

    3. 属性(Property)

      属性的概念对大家来说应该是很熟悉的,类成员函数可以自由地访问本类中的任何属性成员。不过若要从一个类中去访问另一个类中的属性,那就比较麻烦了,所以很多时候我们使用Getxxx和Setxxx方法,这样看起来显得极不自然,比如用Java或者C++,代码是这样的:

      foo.setSize (getSize () + 1);
      label.getFont().setBold (true);

      但是,在C#中,这样的方法被“属性化”了。同样的代码,在C#就变成了:

      foo.size++;
      label.font.bold = true;

      可以看出来,C#显然更容易阅读和理解。我们从这个“属性方法”的子程序代码中,也可以看到类似情况:

    Java/C++:

    public int getSize()
    {
      return size;
    }

    public void setSize (int value)
    {
      size = value;
    }

    C#:
    public int Size
    {
     get{return size;}
     set{size = value;}
    }

      为了区分这种属性化的方法和类的属性成员,在C#中把属性成员称作“域(field)”,而“属性”则成为这种“属性化的方法”专用的名词。顺便说一句,其实这样的属性化方法在VB和DELPHI中是经常碰到的,在VB中它也就叫属性。

      另外,在C#中Get和Set必须成对出现,一种属性不能只有Get而没有Set(在Java和C++中就可以只有Get或者只有Set),C#中这样做的好处在于便于维护,假如要对某种属性进行修改,就会同时注意Get和Set方法,同时修改,不会改了这个忘了那个。

    4、对象索引机制(Indexer)

      C#中引入了对象索引机制。说得明白点,对象索引其实就是对象数组。这里和上一节中的属性联系起来讲一下,属性需要隐藏Get和Set方法,而在索引机制中,各个对象的Get或者Set方法是暴露出来的。比如下面的例子就比较清楚地说明了这一点。

    public class Skyscraper
    {
     Story[] stories;
     public Story this [int index] {
      get {
       return stories [index];
      }
      set {
       if (value != null) {
        stories [index] = value;
       }
      }
     }
    ...
    }

    Skyscraper empireState = new Skyscraper (...);
    empireState [102] = new Story ("The Top One", ...);

      呵呵,有了这种特性,我们就再不用怕课堂上老师叫我们写对象数组这种程序了。
    5. 指代(Delegate)
      指代这个玩意很特别,它有点象指针,但又不完全是,不过大家还是可以把它理解为一种类型安全的、面向对象的指针。(什么是类型安全和面向对象就不用讲了吧?)顺便提一句,有很多书上把Delegate翻译成代理,我觉得这样翻不够确切,翻译成“指代”更恰当些,道理上吻合,并且还符合它的本来意思——微软本来就是用Delegate来“取代指针”,所以叫“指代”,呵呵。

      说起指代,也许至今Sun还会对它愤愤不已,为什么呢?因为在Sun的标准Java中是没有这个东西的,它是微软99年发布的MSVJ++6添加的“新特性”。为此,两家公司吵得不亦乐乎,并且还专门在网上写了大量文章互相攻击,有兴趣的朋友可以去看看(只有英文版)。
    http://www.Javasoft.com/docs/white/delegates.html
    http://msdn.microsoft.com/visualj/technical/articles/delegates/truth.asp

      话归正传,指代有什么特点呢?一个明显的特点就是它具有了指针的行为,就好象从Java又倒回到了C++。在C#中,指代完成的功能大概和C++里面的指针,以及Java中的接口相当。但是,指代比起C++的“正宗指针”来又要高明一些,因为它可以同时拥有多个方法,相当于C++里面的指针能同时指向多个函数,并且是类型安全的,这一点体现了它的“对象”特性;而比起Java的接口来,指代高明的地方在于它能可以不经过内部类就调用函数,或者用少量代码就能调用多种函数,这一点体现了它的“指针”特性。呵呵,很有“波粒二象性”的味道吧?指代最重要的应用在于对于事件的处理,下一节我们将重点介绍。

    6、事件(Event)

      C#对事件是直接支持的(这个特点也是MSVJ所具有的)。当前很多主流程序语言处理事件的方式各不相同,Delphi采用的是函数指针(这在Delphi中的术语是“closure”)、Java用改编类来实现、VC用WindowsAPI的消息系统,而C#则直接使用delegate和event关键字来解决这个问题。下面让我们来看一个例子,例子中会给大家举出声明、调用和处理事件的全过程。


    //首先是指代的声明,它定义了唤醒某个函数的事件信号
    public delegate void ScoreChangeEventHandler (int newScore, ref bool cancel);

    //定义一个产生事件的类
    public class Game
    {
     // 注意这里使用了event关键字
     public event ScoreChangeEventHandler ScoreChange;
      int score;
      // Score 属性
      public int Score
      {
       get {
        return score;
       }
       set {
        if (score != value)
        {
         bool cancel = false;
         ScoreChange (value, ref cancel);
         if (! cancel)
         score = value;
        }
      }
    }


    // 处理事件的类
    public class Referee
    {
     public Referee (Game game)
     {
      // 裁判负责调整比赛中的分数变化
      game.ScoreChange += new ScoreChangeEventHandler (game_ScoreChange);
     }

     // 注意这里的函数是怎样和ScoreChangeEventHandler的信号对上号的
     private void game_ScoreChange (int newScore, ref bool cancel)
     {
      if (newScore < 100)
       System.Console.WriteLine ("Good Score");
      else
      {
       cancel = true;
       System.Console.WriteLine ("No Score can be that high!");
      }
     }
    }

    // 主函数类,用于测试上述特性
    public class GameTest
    {
     public static void Main ()
     {
      Game game = new Game ();
      Referee referee = new Referee (game);
      game.Score = 70;
      game.Score = 110;
     }
    }

      在主函数中,我们创建了一个game对象和一个裁判对象,然后我们通过改变比赛分数,来观察裁判对此会有什么响应。

      请注意,我们的这个系统中,Game对象是感觉不到裁判对象的存在的,Game对象在这里只负责产生事件,至于有谁会来倾听这个事件,并为之作出反应,Game对象是不作任何表态的。

      我们注意到,在裁判类的Referee函数中,Game.ScoreChange后面使用了+=和-=操作符,这是什么意思呢?回到我们定义ScoreChange的地方,可以发现ScoreChange是用event关键字修饰的,那么这里的意思就很明白了:ScoreChange是一个事件,而事件被触发后需要相应的事件处理机制,+=/-=就是为这个事件增加/移除相对应的事件处理程序,而且,并不是一个事件只能对应一个处理程序,我们还可以用这两个操作符为同一事件增加/移除数个事件处理程序。怎么样?很方便吧!

      在实际应用中,和我们上面讲的(竞赛-裁判)机制很相近的系统就是图形用户界面系统了。Game对象可以看作是图形界面上的小零件,而得分事件就相当于用户输入事件,而裁判就相当于相应的应用程序,用于处理用户输入。

      指代机制的首次亮相是在MSVJ里,它是由Anders Hejlsberg发明的,现在又用到了C#中。指代用在Java语言中的后果,则直接导致了微软和Sun之间对类和指针的关系产生了大量的争论和探讨。有意思的是,Java的发明者James Gosling非常幽默地称呼指代的发明者Anders Hejlsberg为“‘函数指针’先生”,因为Anders Hejlsberg总是想方设法地把指针变相地往各种语言中放;不过有人在看了Java中大量地使用了各种类后,也戏称Java的发明者James Gosling为“‘全都是类’先生”,真是其中滋味,尽在不言中啊。  

    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1418414


     
  • 相关阅读:
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第4章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第3章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第1,2章 读书笔记(待更新)
    Tkinter的Message组件
    Git 实操/配置/实践
    mysq5.7.32-win安装步骤
    行为型模式之模板方法
    结构型模式之组合模式
    结构型模式之享元模式
    结构型模式之外观模式
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/2422270.html
Copyright © 2011-2022 走看看