C#和Java之比較(語法篇)


C#和Java作為獨立發展的兩種程序設計語言,其實有很多相似的地方;當然,其中還是有一些不同的點的;假如一個熟悉C#但不清楚java的程序員去寫java程序,其實沒有多大困難,只是如果清楚了C#和Java中的一些不同的點,應該可以更快的從C#過渡到Java的。

本文主要是列舉了筆者在學習Java過程中和C#比較的一些異同。希望可以給同樣從C#轉向Java的開發人員提供一些信息。

IBM的開發者網站提供了一個不錯的java入門系列,對於初學者來說不妨一看。

https://www.ibm.com/developerworks/cn/java/intro-to-java-course/index.html 

另外wiki中其實也已經有一些詳實的對於java和C#的比較,可以參看

https://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java

Namespace(C#) vs Package(java)

C#和java都是面向對象的編程語言;在源代碼的層面,C#的組織結構是命名空間=>類=>方法/變量/常量,而Java稍有不同,用package代替了C#中的namespace,但是所起的作用是類似的。

同樣的,當一個namespace或者package中需要用到其他的命名空間下的類時, C#通過using指定上下文可以訪問的namespace,而Java通過import導入package來達到同樣的目的。

代碼示例

Java

package hello.world; import java.lang.*; public class HelloWorld {
    private static final int CONSTINT = 100;
    private String variable;
    public void method(){}
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

 

C#

using System; namespace Hello.World
{ 
   public class HelloWorld
    {
        private const int CONSTINT = 100;
        private string variable;
        public void Mehtod() { }
        static void Main(string[] args)
        {
            System.Console.WriteLine("Hello World!");
        }
    }
}

 

訪問限定修飾符

C#和Java中,對類型、方法、變量等都可以指定訪問限制修飾,來達到封裝、繼承等等目的。

Java中的訪問限定修飾符的各個訪問限定如下,這個包就是package

public 可由任何類調用
protected 僅能由同一個包中的類或任何子類調用
無修飾符 由同一個包內的任何類調用
private 僅能由定義它的類調用

 

C#中的訪問限定描述如下,這個里面有一個程序集assembly的概念,和namespace不太一樣。

public 可由任何類調用
protected 僅可以被所定義的類型或者其嵌套類型或者其派生類型調用
internal 僅可以被程序集中的類訪問
protected internal 僅可以被所定義類型、派生類型以及任何定義在同一程序集中的類訪問
private 僅能由定義它的類調用
無修飾符 同internal修飾符

 

屬性

C#有Property的概念,通過簡單的get/set就可以定義public屬性;C#中的屬性本質上就是兩個方法,一個setter,一個getter, 只是C#在語言層面提供了友好的支持。

Java就沒有這種語言層面的支持,如果想實現同樣的功能,必須首先定義變量,然后定義一個Set方法,一個get方法;當然現在很多IDE插件可以幫助做第二步自動生成這兩個方法。

示例如下

C#

namespace Hello.World
{
    public class Person
    {
        public int Age { get; set; }
    }
}

 

Java

package hello.world;

public class Person {
    
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 

Foreach

帶有迭代器的類型,都可以使用foreach語法來比較優雅的替換for循環。Java和C#的語法略有不同。

代碼示例如下

C#

namespace Hello.World
{ 
   public class HelloWorld
    {
        static void Main(string[] args)
        {
            foreach (var str in args) 
            {
                System.Console.WriteLine("Hello World!" + str);
            } 
        }
    }
}

 

Java

package hello.world; 

public class HelloWorld {
public static void main(String[] args) {
        for(String str : args){
            System.out.println("Hello World!" + str);
        }
    }
}

 這里順便提一下的是,Java中沒有類似C#中萬能類型var這種定義方式了,所有變量必須要顯示的寫清楚定義類型,這個可能會給寫慣了C#的同學帶來點不適應。

集合

相比於C#, Java內置的集合功能稍顯薄弱,在使用便捷上不如C#。

Java中只有基本的數組類型支持原語類型(int/long/boolean/char  etc), 而其他的集合比如List,Map等只能包含對象類型。而在C#中,所有集合都可以同時支持值類型和引用類型。

C#中,對集合中的元素操作可以使用lamda表達式以及linq的方式,對集合中的每個元素進行操作,選擇,過濾,轉換等等,非常方便。而在Java中,直到java 1.8之后,才支持在集合類型后面,借助類似lamda表達式的方式訪問操作集合中的每個元素,並且內置的功能方法非常少。

一些代碼示例如下,可以看到,使用C#代碼精簡不少,並且有不少內置方法可用(如下代碼不考慮性能開銷,只是純粹展示一下C#中對集合操作的各種可能性)。

C#

using System.Collections.Generic;
using System.Linq;
namespace Hello.World
{ 
   public class HelloWorld
    {
        static void Main(string[] args)
        {
            var persons = new List<Person>();
            persons.Add(new Person() { Age = 21 });
            persons.Add(new Person() { Age = 19 });
            persons.Where(p => p.Age > 20).Select(p => p.Age).ToList().ForEach(p => System.Console.WriteLine("Age-{0}", p));
        }
    }
}

 

Java

package hello.world;

import java.util.ArrayList;
import java.util.List;

public class HelloWorld {

    public static void main(String[] args) {

        List<Person> persons = new ArrayList<Person>();
        Person p1 = new Person();
        p1.setAge(21);
        persons.add(p1);
        Person p2 = new Person();
        p2.setAge(19);
        persons.add(p2);
        persons.forEach(p -> {
            if (p.getAge() > 20) {
                System.out.println(String.format("Age-%s", p.getAge()));
            }
        });
    }
}

 繼承和多態

C#和Java都很好的支持面向對象編程,只是在具體編碼上稍微有些不一樣。

主要在兩點,子類構造的時候對父類的構造;重寫。

構造的傳值這塊,C#把調用父類的構造方法移出到函數外面調用,以示區別,個人覺得這個比較人性化。

重寫這里,Java父類中的任何方法都可以被重寫,只要加上@Override的注解;而C#中需要在父類可能被重寫的方法加上virtual關鍵字,后續子類重寫時,在使用關鍵字override;感覺C#更加嚴謹一些。

另外,C#和Java中限定一個類不能被繼承的關鍵字也不一樣,C#使用sealed,Java是final。

代碼示例如下

C#

namespace Hello.World
{
    public class Person
    {
        public virtual void doAction() 
        {
            System.Console.WriteLine("Person");
        }
    }

    public class Employee : Person
    {
        public Employee()
            : base()
        { 
        }

        public override void doAction()
        {
            System.Console.WriteLine("Employee");
        }
    }
}


namespace Hello.World
{ 
   public class HelloWorld
    {
        static void Main(string[] args)
        {
            Person p = new Employee();
            p.doAction();
        }
    }
}

 

Java

package hello.world;

public class Person {
        
    public void doAction(){
        System.out.println("Person");
    }

}

public class Employee extends Person{
    
    public Employee(){
        super();
    }
    
    @Override
    public void doAction(){
        System.out.println("Employee");
    }

}

    public class HelloWorld {
    
        public static void main(String[] args) {
    
            Person p = new Employee();
            p.doAction();
        }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM