c#语法与c++ 及 java语法的对比分析
早期开发的时候一直用c/c++,后来主要用的是java。最近需要用下c#。
熟悉了下c#,发现c#语言在对c/c++基础上做了很多简化,同时参考了很多java的语法习惯,本来在语法上c/c++就有很多和java类似的地方,现在c#就类似的地方更多了,不过还是有很多区别。
本文总结下c# 和c++及 java的语法差别,重点比较与java的区别,便于相互学习,加强理解。
一、c#与c++的区别
相比c++,c#做了很多简化,使的编写代码更加容易,重要的变化由如下方面:
1、抛弃了指针的使用。在c#中没法使用指针了,在对象成员的调用也只有一种方式,就是通过 . 来引用。
2、完全面向对象。在c#中,不再有全局的函数了。所有的代码都必须在类中。连基本的基本类型都有方法,如:
class Myapp
{
private static void Main(string[] args)
{
int a = ;
string value = a.ToString();
int b = int.Parse(value);
}
}
3、没有了头文件的概念,类的定义和实现都在类中。
4、引入了命名空间的概念,用于划分源代码,类似java的包的概念。
5、类的继承上废除了多继承的概念,一个类智能有一个父类,而在c++中可以有多个父类。
6、引入了类似java中的接口概念。
7、引入了属性的概念,简化了对成员变量的操作。
下面我们重点介绍c# 与java的对比。
二、c#与java基本语法的对比
1、程序框架
同java一样,c#要求所有的代码都要在类中,不再同c++一样,既可以定义类,也可以定义全局的方法。
java程序的入口代码必须是某个类中的如下的方法 :
public static void main(String[] args);
而在c#中,入口方法是
static void Main(string[] args)
注意:c#中Main的第一个字母M是大写,且Main方法的参数可以不定义。方法的修饰符也可以不加public。
2、包和命名空间
在java中,通过包来组织java源文件。在c#中,通过命名空间来组织c#源文件。 它们的含义和作用是类似的。
区别是,java强制要求java源文件的存放补录必须与包路径严格一致。
在java中,通过import引入包,而在c#中通过using引入命名空间。
两者都可以通过全路径来引用类(这样就不需要import和using了)。
3、基本数据类型
两者大部分基本类型的名称都一样,如 int ,char等。枚举定义的关键字都是 enum。数组定义和使用语法也是类似。
典型的区别是:
1)布尔型在java中是 boolean,而在c#中是bool。
2)字符串类型名在java中 是 String ,而在c#中是 string (第一个字母s是小写)。
最关键的是在java中进行字符串内容的比较要用 equlas方法,而在c#中直接可以用 == 比较。
4、语句
两者的 if 语句,switch语句,for,while, do ...while,break, continue 使用方式都一致。
有个区别是,在java中,可以用for循环遍历集合。而在c#中需要用单独的关键字 foreach来遍历,但使用方法一样。
三、c#与java面向对象语法的对比
java和 c# 都是通过 class关键字来定义类,也都不需要头文件。类的实现代码用 { }扩起。
1、类的成员
c#中引入了一个属性的概念。
我们知道在java中,为了提高安全性,我们定义成员变量一搬建议定义private的,这样为了其它类能访问该变量,再定义相应的get 和 set 方法,代码如:
class A{
private int num;
public void setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}
} class B{
public void test(){
A a = new A();
a.setNum();
int num = a.getNum();
}
}
而在c#中,为了简化操作,引入了一个属性的概念,举例如下
class A
{
public int num { get; set; }
} class B
{
public void test()
{
A a = new A();
a.num = ;
int re = a.num;
}
}
在类A中,定义了一个属性 num,在类B中,直接通过属性名可以访问,简化了java中的语法。
在A中定义num时,可以只有get或set标记,表示只读或只写的。
上面的方式存在一个问题,如果在get或set操作时需要通过一定的计算来返回值,既可以采用如下的代码方式。调用方法不变。
class A
{
private int _num;
public int num
{
get { return _num; }
set { _num = value*; }
}
}
与上面相比,先定义了一个普通的变量_num(这里是private的,不让外部直接访问)。
然后定义了一个属性num,并且有相应的代码,其中set代码中的 value是隐式参数,是在给属性设置值时传入的参数。
这和java代码的使用方式类似了,只是省去了需要定义 setXXX类似的方法。 另外调用时简化了,直接通过属性名就可以。
2、访问修饰符
在java中,有 public, protected,private 和 缺省四种级别的修饰符,在定义类和成员时不加修饰符,默认是缺省的。
在c#中,缺省修饰符需要显示的用internal关键字标识,并且如果定义时不加修饰符,默认不是internal 而是 private的。并且在c#中,可以 protected internal组合使用,其含义是访问仅限于该类或当前程序集(同一命名空间)的派生类。单独的protected范围比protected internal大,允许的派生类不限于当前程序集,加上了internal将派生类限制在当前程序集。
3、类的继承语法
两者都支持类的继承,在c++中支持多个父类,在c#中进行了简化,同java一样,一个类只允许有一个父类。
在java中通过extends关键字继承类,在c#中采用的是c++的语法,用 :后跟父类表示。两者对父类构造函数的处理机制也不一样。下面举例说明。
下面代码是java的例子:
class A{
private int num;
public A(int num){
this.num = num;
}
} class B extends A{
public B(int num) {
super(num);
//其它代码,super语句必须放在第一行。
}
}
可以看出,在java中使用extends关键字来继承父类,用 super方法来调用父类的构造函数。
下面是c#的代码
class A{
private int num;
public A(int num){
this.num = num;
}
} class B : A{
public B(int num):base(num) { }
}
可以看出,在c#中是通过 : 标识符来继承父类,而且是通过base关键字来调用父类构造函数。
4、接口
在java中,引入了接口类型,一个类可以实现一个或多个接口.
在c#中,参考java引入了接口的机制,注意在c++中没有接口的机制。
但两者在实现接口的语法上有些区别,在java中通过implements关键字来标识,而在c#中,使用同继承一样。
下面是java的语法例子
interface hello1{}
interface hello2{} class A implements hello1,hello2{
private int num;
public A(int num){
this.num = num;
}
} class B extends A implements hello1,hello2{
public B(int num) {
super(num);
//其它代码,super语句必须放在第一行。
}
}
在java中,当一个类同时需要继承父类和实现接口时,extends语句要放在 implements语句前。
下面是c#的语法例子
interface hello1 { }
interface hello2 { }
class A:hello1,hello2{
private int num;
public A(int num){
this.num = num;
}
} class B : A,hello1,hello2{
public B(int num):base(num) { }
}
在 c#中,当一个类同时需要继承父类和实现接口时,因为都是跟在 : 后面,需要将父类名放在前面,接口名在后面,如上面例子。
5、重载、重写(多态)
所谓重载,就是一个类可以有多个方法,方法名一样,但参数信息不一样。这个java和 c#都支持。
所谓重写,是面向对象编程中多态特性的体现。就是子类可以定义和父类一样的方法,具体执行时是执行父类方法还是子类方法,动态根据实例绑定。java和c#都有这个特性,区别是使用语法上有些不同。
java的例子:
package com; public class Demo {
public static void main(String[] args) {
A a = new A();
a.show(); //输出的是 i am A B b = new B();
b.show(); //输出的是 i am B A c = new B();
c.show(); //输出的是 i am B. 多态体现,动态决定调用父类或子类方法。因为c实际是指向B的实例
}
} class A {
public void show() {
System.out.println("i am A");
}
} class B extends A {
public void show() {
System.out.println("i am B");
}
}
可以看出,子类B通过定义相同的方法,重载了父类A的方法。实际执行时,根据变量指向的具体实例决定调用是父类或子类的方法。
c#的例子,c#在多态上的语法参考了c++的特点,需要通过virtual和override关键字来标识。
class Myapp
{
private static void Main(string[] args)
{
A a = new A();
a.show(); //输出的是 i am A B b = new B();
b.show(); //输出的是 i am B A c = new B();
c.show(); //输出的是 i am B. 多态体现,动态决定调用父类或子类方法。因为c实际是指向B的实例
}
} class A {
virtual public void show() {
System.Console.WriteLine("i am A");
}
} class B : A {
override public void show() {
System.Console.WriteLine("i am B");
}
}
可以看出,在c#中,要想实现继承的多态性,需要在父类方法中用virtual关键字标识,然后在子类的方法中用override关键字进行标识。
需要说明的是,对于父类定义的virtual或非vritual方法,子类可以不重载,但也可以定义同样的方法(没有用override关键字),这是允许的,这时子类的该方法将隐藏父类的方法,这个不是动态的特性。
6、抽象类和抽象方法
有时在父类中定义一个序方法,但该方法在基类中不需要有具体的实现,需要在子类中实现。这个特性java和c#都支持。
只是语法上有细微差别。这里举例说明下。
java的例子:
package com; public class Demo {
public static void main(String[] args) {
B b = new B();
b.show(); //输出的是 i am B A c = new B();
c.show(); //输出的是 i am B. 多态体现,动态决定调用父类或子类方法。因为c实际是指向B的实例
}
} abstract class A {
public abstract void show();
} class B extends A {
public void show() {
System.out.println("i am B");
}
}
在java中,是通过abstract关键字标识抽象类和抽象方法的,具体有如下细节:
1)一个类有抽象方法,其所在的类必须定义为抽象类。
2)子类继承抽象父类,要么实现父类的抽象方法,要么继续把自己定义为抽象类。
3)抽象方法没有方法体。抽象类不能实例化。
下面是c#中的例子
class Myapp
{
private static void Main(string[] args)
{
B b = new B();
b.show(); //输出的是 i am B A c = new B();
c.show(); //输出的是 i am B. 多态体现,动态决定调用父类或子类方法。因为c实际是指向B的实例
}
} abstract class A {
abstract public void show();
} class B : A {
override public void show() {
System.Console.WriteLine("i am B");
}
}
除了子类方法定义需要加override关键字,其它语法要求与java一样。另外对抽象类和抽象方法的要求也与java中的要求一致。
四、c#与java其它对比
1、常量和只读字段
在java中,可以通过final来定义只读变量,可以使成员变量,可以是方法的内的局部变量,也可以是形参。并且定义和初始化可以一起,也可以分开。
如果是定义的的final成员变量,则需要在构造函数中初始化。 如果是方法内的局部变量,可以在定义后赋值。
在c#中,可以用 const关键字定义常量,要求必须在定义时理解赋值。
在c#中,还可以用 readonly来定义类的成员(注意不能定义局部变量),可以在定义时赋值,也可以定义时不赋值,而在构造函数中赋值。
2、异常处理
java和 c#有类似的异常处理机制和语法,都有 try, catch, finally, throw 这几个使用关键字。 区别是:
1)java中的异常分为检查时异常和运行期异常两种,而c#中只有一种(运行期异常)。
2)在java中 ,catch语句必须带异常类型参数。
而在c#中,可以不带,表示是缺省的,表示对所有异常处理,但如果定义了多个异常,不带参数的必须放在最后。
3、参数传递
在java中,参数传递只有值传递一种方式。对于基本数据类型,如 int等,在方法内无法修改方法的值。
而在c#中,保留了c/c++的特性,通过 ref 和 outer 关键字,可以让形参和实参指向同样的值,这样在方法内修改形参的值,方法外的实参值也跟着变化。
不过,为了提高程序的可读性,建议少用这种特性。
4、内部类
在java中,支持内部类,包括匿名内部类。但在c#中,支持内部类,但不支持匿名内部类。
如下面的匿名内部类在java中是允许的,但在c#中是不行的。
package com; public class Demo {
public static void main(String[] args) {
A a = new A() {
public void show() {
;
}
};
a.show();
}
} abstract class A {
public abstract void show();
}
5、分部类
在c#中,编写代码时可以将一个类的定义分到多个cs文件中,后续由编译器自动合并。这个在java中不支持。
这个特性感觉很不好,强烈建议正常情况下不要使用。
c#语法与c++ 及 java语法的对比分析的更多相关文章
- Java和.net对比分析
.Net和Java是国内市场占有率最高的两门技术,对于准备学习编程语言的初学者来说,.Net和Java是初学者首先考虑的两门技术,因此很多人一遍遍的问“学.Net还是学Java”,社区中也每天都有“. ...
- java Map集合对比分析
1.Map:Map是所有map集合的顶级父接口,用于key/value形式的键值对,其中每一个key都映射到一个值,key不能重复. 2.TreeMap:该map将存储的键值对进行默认排序,并且还能够 ...
- Java语法
java语法: 一个java程序可以说是一系列对象的集合,而这些对象都要通过调用彼此的方法来协同工作. 对象: 对象是一个实例,例如:一只猫,它是一个对象,有状态和行为.它的状态状态有:颜色,名字,品 ...
- Java语法糖4:内部类
内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...
- Java语法糖1:可变长度参数以及foreach循环原理
语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...
- Java程序员学C#基本语法两个小时搞定(对比学习)
对于学习一门新的语言,关键是学习新语言和以前掌握的语言的区别,但是也不要让以前语言的东西,固定了自己的思维模式,多看一下新的语言的编程思想. 1.引包 using System;java用import ...
- 程序员带你学习安卓开发,十天快速入-对比C#学习java语法
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...
- Java语法基础(1)
Java语法基础(1) 1. Java是一门跨平台(也就是跨操作系统)语言,其跨平台的本质是借助java虚拟机 (也就是JVM(java virtual mechinal))进行跨平台使用. ...
- C++、Java语法差异对照表
C++.Java语法差异对照表 C++ and Java Syntax Differences Cheat Sheet First, two big things--the main function ...
随机推荐
- Splunk
http://www.huxiu.com/article/33724/1.html http://www.netis.com.cn/splunk/%E4%BB%80%E4%B9%88%E6%98%AF ...
- AOP 面向切面编程、拦截器
AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术.它是一种新的方法论, ...
- Sicily-1156
一. 模仿树的的先序遍历.范围是1000个节点.用数组存储节点的信息. 二. 要注意的是,头结点是不确定的,所以在前序遍历之前要找出头结点,除了头结点的下标值出现一次之外,其他结点 ...
- poj 1077 Eight(双向bfs)
题目链接:http://poj.org/problem?id=1077 思路分析:题目要求在找出最短的移动路径,使得从给定的状态到达最终状态. <1>搜索算法选择:由于需要找出最短的移动路 ...
- I can do it!(贪心)
I can do it! Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- 全栈JavaScript之路(七)学习 Comment 类型节点.
凝视 在DOM中,用 Comment 类型 节点表示, 构造器函数为: function Comment(){[native code]}. comment 节点的特征: nodeType:8 no ...
- Floodlight之 FloodlightContextStore 数据结构
FloodlightContextStore 代表的是一种缓存模型(利用的是ConcurrentHashMap).里面存储的是上下文相关的对象,可以依据对应的key得到详细的 Object. ...
- [学习笔记]jQuery实现一些动画效果的方法
jQuery实现效果的方法 1,隐藏和显示:hide(),show(),toggle() // [ˈtɑ:gl]切换 语法: $(selector).hide(speed,callback); $( ...
- ADO.NET(一) 空间 ADO.NET结构 命名空间(车延禄) System.Data—— 所有的一般数据访问类 S(转载)
ADO.NET(一) 空间 ADO.NET结构 命名空间(车延禄)System.Data—— 所有的一般数据访问类System.Data.Common—— 各个数据提供程序共享(或重写)的类Sys ...
- ios7以上自定义导航栏标题的字体大小及颜色的方法
自定义导航栏的字体和颜色,只需要自定义一个lable,然后将lable添加到导航栏的titleview中就可以了 代码如下 UILabel *label = [[UILabel alloc] init ...