【c#系列 二】从java到.net 基础
来源:互联网 发布:ab测试 算法 编辑:程序博客网 时间:2024/05/16 10:56
文章主要目标是让一个java程序员如何迅速适应.net的开发环境,在上一篇已经讲到了开发环境的安装,接下来计划使用两篇博客迅速上手C#,这是第一篇,主要从基础语法和一些简单操作里来体现,通过对比学习的方法,更加深刻的掌握.net的用法和规则,因为楼主即将转向.net开发,所以这里在对比阐述的时候会对c#重点分析。
学习内容来源于:
菜鸟教程http://www.runoob.com/csharp/csharp-methods.html
C#与Java不同的地方
整体结构
整体结构的不通风主要体现在层次架构上,java的结构是 项目–包–类(成员变量+成员方法)。而C#则是使用 解决方案–命名空间–类(成员变量+成员函数),接下来从以下几个方面,对整体上的一些不同进行详述。
程序结构
- 程序的第一行 using System; - using 关键字用于在程序中包含 System 命名空间。 一个程序一般有多个 using 语句。相当于java里的import,引入你需要的包
- 下一行是 namespace 声明。一个 namespace 是一系列的类。HelloWorldApplication 命名空间包含了类 HelloWorld。相当于java里的包,该包下可以有很多类
- 下一行是 class 声明。类 HelloWorld 包含了程序使用的数据和方法声明。类一般包含多个方法。方法定义了类的行为。在这里,HelloWorld 类只有一个 Main 方法。相当于java里的类
- 下一行定义了 Main 方法,是所有 C# 程序的 入口点。Main 方法说明当执行时 类将做什么动作。
基本语法
语法上的不同,体现在标识符上,而这时唯一的区别就是,java使用的特殊字符是$符,而C#使用的是@符。
输入输出
- 输出语句
Console.WriteLine("Hello World");
用于向控制台输出语句,类似于java里的System.out.println()。
在输出上java显然更好用一些,直接字符串和参数拼接,而C#需要使用占位符
static void Main(string[] args){ Console.WriteLine("A:{0},a:{1}",65,97); Console.ReadLine();}
输出顺序与占位符顺序一一对应。
输入语句
Console.ReadLine("Hello World");
用于读入用户输入的数值,类似于java里的Scanner,不过比Scanner方便了很多Console.ReadKey(); 是针对 VS.NET 用户的。这使得程序会等待一个按键的动作,防止程序从 Visual Studio .NET 启动时屏幕会快速运行并关闭。
继承和实现的书写
- java里的继承使用extends关键字,实现使用:关键字,而C#统一使用:,在书写规范上C#推荐接口用I开头来区别类和接口的不同。
- java里子类调用父类方法或者实现父类构造方法使用super关键字,而在C#里使用base关键字
成员变量
成员变量的不同体现在一些常量,不同的变量,C#定义较为繁琐
常量
C#里的常量使用专用关键字const,而java则使用final。之后还会提到C#定义不可继承方法的时候有专用关键字sealed,而java依旧使用final。
数据类型
对于值类型
C#的数据类型里多了很多无符号的值类型,而且多了一个精度更高的 decimal类型。
对于引用类型
对象类型,字符串类型不用多数,主要的不同就是动态类型,相对于java里的“假”的泛型,我感觉C#的泛型可以说是真泛型了
对于指针类型
C#官方都说了是不安全方式,我感觉有指针的存在只是为了照顾之前的C和C++的学习者吧。
类型转换
类型转换上,C#似乎更方便,提供了很全面的方法,显式转换与隐式转换与java大同小异。
可空类型
该类型在java里并不存在,也不知道这种类型存在的意义
定义
C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值
using System;namespace CalculatorApplication{ class NullablesAtShow { static void Main(string[] args) { int? num1 = null; int? num2 = 45; double? num3 = new double?(); double? num4 = 3.14157; bool? boolval = new bool?(); // 显示值 Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}", num1, num2, num3, num4); Console.WriteLine("一个可空的布尔值: {0}", boolval); Console.ReadLine(); } }}
运行结果
显示可空类型的值: , 45, , 3.14157一个可空的布尔值:
合并运算符
Null 合并运算符用于定义可空类型和引用类型的默认值。Null 合并运算符为类型转换定义了一个预设值,以防可空类型的值为 Null。Null 合并运算符把操作数类型隐式转换为另一个可空(或不可空)的值类型的操作数的类型。
如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。下面的实例演示了这点:
using System;namespace CalculatorApplication{ class NullablesAtShow { static void Main(string[] args) { double? num1 = null; double? num2 = 3.14157; double num3; num3 = num1 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3); num3 = num2 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3); Console.ReadLine(); } }}
运行结果
num3 的值: 5.34num3 的值: 3.14157
成员方法
访问修饰符
C#提供了5种级别的访问修饰符限定
Private:对象本身在对象内部可以访问;和java一样
Internal:同一个程序集的对象可以访问(对应于java里的default);
Protected:只有该类对象及其子类对象可以访问同一个包中不能访问,这个算是C#比较特有的。
Protected internal:该程序集内的派生类访问,是protected和internal的交集(Protected Internal 访问修饰符允许在本类,派生类或者包含该类的程序集中访问。这也被用于实现继承。);和java里的protected一样
Public:所有对象都可以访问;和java一样
方法的参数传递
前两种与java的相同,主要区别在于C#多了一种叫做“输出参数”的传递形式。看了很多,理解到,输出参数最重要的作用就是:当需要从一个参数没有指定初始值的方法中返回值时,输出参数特别有用
using System;namespace CalculatorApplication{ class NumberManipulator { public void getValues(out int x, out int y ) { Console.WriteLine("请输入第一个值: "); x = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入第二个值: "); y = Convert.ToInt32(Console.ReadLine()); } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* 局部变量定义 */ int a , b; /* 调用函数来获取值 */ n.getValues(out a, out b); Console.WriteLine("在方法调用之后,a 的值: {0}", a); Console.WriteLine("在方法调用之后,b 的值: {0}", b); Console.ReadLine(); } }}
要知道,这里a,b都没有赋初值,但是依然可以使用,这就是输出参数的好处所在。
请输入第一个值:7请输入第二个值:8在方法调用之后,a 的值: 7在方法调用之后,b 的值: 8
重写
几个区别比较大的地方
1,C#里是通过抽象类:虚方法virtual和abstract实现动态多态
抽象方法
和虚方法类似,只不过没有方法体,和java的类似。
虚方法
和java里的普通方法类似,但感觉更加规范了,只有需要重写的时候才尽量用virtual方法,其它时候用普通方法。java这块儿就比较模糊了(只要方法名相同,就默认重写)。Java默认的多态,C#要求加上virtual(被继承的方法)和override(继承的方法),而且C#要求不能改变原来的访问修饰符,不像java那样,可以指定更加宽松的访问方式。如果有人利用C#来写程序,必须经常带上virtual和override,还必须照抄原来的访问控制符
using System;class A{ public void F() { Console.WriteLine("A.F"); } public virtual void G() { Console.WriteLine("A.G"); Console.ReadKey(); }}class B : A{ new public void F() { Console.WriteLine("B.F"); } public override void G() { Console.WriteLine("B.G"); Console.ReadKey(); }}class Test{ static void Main() { A a= new B(); a.F(); a.G(); }}
输出结构
A.F //编译看左边,运行看右边,编译看非虚,运行看虚方法B.G
感觉virtual这个关键字有点儿鸡肋,觉的还是java的方便理解一些
sealed方法
其实和java里的final差不多,修饰的类不可继承
一些结论
1,C#和java最大的区别就是java各方面规定比较宽泛,而C#则粒度更加细致,每个方面都规定的特别多详细
2,如果说写代码的体验,肯定是java更好一点儿,不是那么细分,比较好理解,但有些东西规范的比较宽泛,出了错不好排错。如果搭配ide来食用的话,感觉C#+2015食用起来更佳,很多便于团队协作和注释之类的设置,而且2015功能非常强大,但鸡肋的地方就是每次调试都要出框,关了才能修改,比较麻烦,当然也有可能是我现在还没有熟练使用的原因。
C#额外可使用的地方
结构体
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
- 与类不同,结构不能继承其他的结构或类。结构不能作为其他结构或类的基础结构。结构可实现一个或多个接口。
- 结构成员不能指定为 abstract、virtual 或 protected。
- 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
不知道该怎么形容结构体,感觉就是为了适用之前的C强行加的。
析构函数
可能是因为没有JVM如此强大的垃圾回收能力吧,所以使用析构函数来弥补CLR的不足吧,但好像官方也不怎么推荐这个功能。
预编译与条件指令
1,预处理器指令指导编译器在实际编译开始之前对信息进行预处理。
所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
2,C# 编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。在 C# 中,预处理器指令用于在条件编译中起作用。与 C 和 C++ 不同的是,它们不是用来创建宏。一个预处理器指令必须是该行上的唯一指令。
未完待续,现在只是粗浅的认识,之后随着学习的深入会一直更新。。。
- 【c#系列 二】从java到.net 基础
- 【c#系列 三】从java到.net 高级
- 【c#系列 四】从java到.net 核心
- Java开发系列--JDBC(从基础到封装)
- 从 c# 到java
- 从JAVA到.NET
- 从.NET到Java
- 从.net到java
- 从.Net到Java
- Java之------IO从基础到加强(二)
- .Net Discovery 系列之二--string从入门到精通(下)
- IC设计基础系列之CDC篇7:从CMOS到触发器(二)
- 从c++到java (二)
- 从c++到java (二)
- 喜新厌旧:从Java到.Net
- asp.net从入门到精通看书笔记.一些c#语言基础
- Java基础复习系列二
- java基础系列(二)
- hello
- CentOs日常问题集锦(持续更新......)
- Material Design实战之ToolBar
- ios获取手机IP地址
- java 并发编程实战书籍学习 第五章,CountDownLatch,FutureTask,CyclicBarrier,Semaphore学习
- 【c#系列 二】从java到.net 基础
- springcloud 总 架构图
- composer 安装laravel 框架
- 照片处理小工具三合一设计到实现(一)
- 试图学习tensorflow的人啊。
- 什么事数据对象以及属性分为什么类型?
- web错误代码
- Centos 6.5下安装Java
- 监听文件变化后合并文件