java与c#的区别、两者有什么不同?_其它相关

Java 的设计者是因为讨厌C++的复杂,于是Java 非常简洁,GC 也让内存管理非常方便,C# 是看中了Java 的GC,和虚拟机技术,希望把微软的几大语言集成到.NET 上来。 因此C#从语言上来讲并不简单甚至可以算的上复杂。

两种语言的设计思路也不一样,Java 是编译解释语言,C#是编译然后编译运行语言。Java 没有委托,C# 有委托。Java 倾向于用Interface 实现委托的功能,而 在C# 中,Abstract Class 比Interface 发挥了更大功能。

Java 遵循camel 命名规则,C#遵循Pascal 命名规则。但是如今越来越多的Java 人开始使用C#, 同时也把camel 命名规则带到了C#,这可能会让C#代码越来越难读。为什么当初C#为什么不遵循camel 呢? 我看不出camel 命名规则有什么不好的。

一. 类名.this 与内部类

在 java 中,经常看到类似类名.this 的用法,this 就是当前对象实例,为什么前面会出现类名呢?对此 C# 程序员会很纳闷。

在 Java 中,很多地方使用到了内部类,甚至可以在在内部类中访问外部类中的成员,这个时候,在内部类中使用 this 的时候,就会出现 this 到底是谁的问题,到底是表示内部类的当前对象实例,还是外部类的当前对象实例问题。

在 Java 中,通过在 this 的前面加上外部类的类名,表示在内部类中使用外部类的当前对象实例。

我们看下面的一个例子。

复制代码 代码如下:

package core.sisheng;

// 外部类定义
public class OuterClass {

    // 内部类定义
    private class InnerClass
    {
        // 内部类中没有定义 id 成员,这里访问外部类中的成员
        public int getId(){    return OuterClass.this.id;    }
        public void setId(int id) { OuterClass.this.id = id;}

        // 内部类中定义了 name 成员,直接访问内部类中的成员, 默认 this 访问当前类中的成员
        private String name;
        public String getName() { return this.name;}
        // 可以在 this 的前面加上一个内部类的名称
        public void setName(String name) { InnerClass.this.name = name;}

        // 内部类中也可以访问外部类中同名的成员,需要加上外部类的名称
        public String getOuterName() { return OuterClass.this.name;}
        public void setOuterName(String name) { OuterClass.this.name = name;}

        @Override
        public String toString()
        {
            return "Id: " + this.getId() + ", Inner Name: " + this.getName() + ", Outer Name: " + this.getOuterName();
        }
    }

    // 外部类中定义的成员 id 和 name
    private int id;
    private String name;

    private InnerClass innerInstance;
    public OuterClass()
    {
        this.innerInstance = new InnerClass();
        this.innerInstance.setId(20);
        this.innerInstance.setName("Tom");
        this.innerInstance.setOuterName("Alice");
    }

    public String toString()
    {
        return this.innerInstance.toString();
    }   
}

在C#中,类区分为嵌套类和非嵌套类,前者是声明在其他数据类型内部的类。后者是直接定义在某一个命名空间的类。C# 中很少定义嵌套类。

非内嵌类只允许使用public和internal的访问控制,而内置类则允许使用所有的五种访问控制符,private, protected , internal protected,public和internal。内部类也可以访问外部类的所有方法,包括instance方法和private方法,但是需要显式 的传递一个外部类的实例。

C#中的内部类能够使用外部类定义的类型和静态方法,但是不能直接使用外部类的实例方法,因此,不存在上面的问题。

在C#中,外部类对于内部类的作用更像是一个命名空间,只要访问控制允许,就可以使用下面的方法创建内部类对象实例。

OuterClass.InnerClass  obj = new OuterClass.InnerClass();这个实例与外部类的任何实例没有任何直接的关系。类似于Java中的静态内部类。

二、类名.class 与类型

在 java 中还经常看到类名.class 的用法,这个用法相当于  C# 中的 typeof( 类名 ),用来获取类型的类型对象实例引用。

java中,每个class都有一个相应的Class对象,当编写好一个类,编译完成后,在生成的.class文件中,就产生一个Class对象,用来表示这个类的类型信息。获得Class实例的三种方式:

通过调用对象实例的 getClass() 方法获取该对象的Class实例。

使用Class的静态方法forName(),用类的名字获取一个Class实例。Class.forName(xxx.xx.xx) 返回的是一个类, 作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。

类名.calss的方式获取Class实例,对基本数据类型的封装类,还可以采用.TYPE来获取对应的基本数据类型的Class实例。

C# 中获取类型对象实例的方式更加简单明确一些。

通过调用数据实例的 GetType() 方法获取,这个方法继承自Object,所以C#中任何对象都具有GetType()方法,x.GetType(),其中x为变量名。

typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。

通过 System.Type 的静态方法 System.Type.GetType()。

 三、匿名类

在 java 中,匿名类的使用也比较多,比如在 Android 中,实现按钮的监听,经常会看到类似这样的代码。

复制代码 代码如下:

this.listener0 = new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        Intent intent = new Intent( MainActivity.this, ActivityFrameLayout.class);
        setTitle("FrameLayout");
        startActivity( intent );
    }
};

在这里,OnClickListenter 实际上是一个接口,接口能用来创建对象实例吗?当然不能。

所以,java 在这里自动创建一个实现接口的匿名类,我们创建出来的实际上就是这个匿名类的对象实例。

这样做的好处就是我们没有必须再定义一个只使用一次的类,然后再通过这个类创建对象实例,简化了程序的开发。

比如,我们有下面的一个接口。

复制代码 代码如下:

public interface myInterface {
    void onClick();
}

就可以通过接口创建一个实现接口的匿名类的对象实例,然后使用这个对象实例。

复制代码 代码如下:

myInterface instance = new myInterface(){
    @Override
    public void onClick()
    {
        System.out.println("Clicked!");
    }
};

instance.onClick();在 C# 中,我们根本就不会使用这种形式,通过委托,可以非常简单地实现同样的功能。

 注意,java 中是没有委托的。

如果我们输出一下这个实例的类型,你会看到这个匿名类的实际类型的。

复制代码 代码如下:

System.out.println( instance.getClass());
// class core.sisheng.Study1$1四、属性(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方法,同时修改,不会改了这个忘了那个。

五、对象索引机制(Indexer)

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

复制代码 代码如下:

public class Skyscraper 

 Story[] stories; 
 public Story this [int index] { 
get { 
 return stories [index]; 

set { 
 if (value != null) { 

stories [index] = value; 
 } 

 } 
... 
}

以上介绍C#和JAVA得不同点,希望对你了解C#和JAVA有所帮助。

时间: 2024-09-29 16:43:13

java与c#的区别、两者有什么不同?_其它相关的相关文章

编程语言 c++应用方向-C++,VB,Java等编程语言的区别及应用领域

问题描述 C++,VB,Java等编程语言的区别及应用领域 作为一个新手,我想知道Visual C++和Visual Basic,Java的区别,我学的是C++,但是不知道用C++可以做些什么,希望有高手指明一下方向. 解决方案 我个人认为,C更接近底层设备,也就是说一般c用来和硬件打交道,java更适合一些应用程序的编写,学习C++其实就是从C到java的一个过渡!面向过程编程到面向对象编程的过度! 解决方案二: c++语言是面向对象的编程语言,它认为世间一切都是由对象(object)组装起来

java equals和==的区别详解_java

大概说equals和==都比较的是什么: 1. boolean tem = a == b; 首先==比较的肯定是地址,从堆栈的角度说也就是说==比较的是栈上面的内容.因为栈是用来存放地址或是java中八大基本类型中自动变量的字面值(自动变量就是用int a = 1;这种形式来定义的变量).如果是自动变量比较值的话肯定是用==来比较,因为equals()是一个方法,所以必须由对象调用才可以用于比较.而自动变量既不是类的实例也不是类的引用所以不能用equals()方法. 2.boolean tem

浅谈java中Math.random()与java.util.random()的区别_java

今天突然想起来,java产生随机数的问题,上机试了一下,找到了一点区别,在这里总结一下: 直接调用Math.random()是产生一个[0,1)之间的随机数, 如果用 java.util.Random random=new Random();random.nextInt() 这样产生一个长整型的随机数并且与上一次是一样的,如果过一会再产生就不会一样了,例如: for (int i = 0; i < 10; i++) { Random random=new Random(); Thread.sle

java.lang.ClassNotFoundException与java.lang.NoClassDefFoundError的区别

以前一直没有注意过这个问题,前两天机缘巧合上网查了一下,然后自己测试验证了一下.虽然网上说法很多,但是关于NoClassDefFoundError并没有给出一个样例,所以一直无法理解,索性自己验证了一下,收获还不少. ClassNotFoundException ClassNotFoundException这个错误,比较常见也好理解. 原因:就是找不到指定的class. 常见的场景就是: 1 调用class的forName方法时,找不到指定的类 2 ClassLoader 中的 findSyst

Java application和applet区别

下面哪一项不是Java application和applet的不同点? A.applet中不再需要main()方法 B.Java applet有Web browser执行 C.执行方式不同 D.applet由若干个类构成 答案是:D 以前在学习java的时候听说过这个东西,只是知道这个东西不在运用了,不过这个东西到底是什么不知道,今天看到这样的一个问题,我开始研究了一下这个applet.下面是在网上搜集到的信息: =========================================

C和CPP的区别 &amp;amp; C++,Java and Python的区别

今天在论坛上看到两个学神讨论C++的优劣性引申出来的各种问题,深深感觉自己差距很大,现就部分问题做个小的总结. C和CPP的区别: 1. C没有bool类型.布尔类型是int.0是假,非0是真.   2. C里字符常量(如'a'.'\n'.'\0'等)是int型,而C++里是char型.但这不影响使用.   3. 没有引用类型的变量,一般使用指针.函数的参数也不能是引用类型,想要副作用请用指针.   4. 没有模版.可以用宏代替.但是C99开始支持inline,用法和C++一样. (C99 is

Java千百问_05面向对象(011)_引用传递和值传递有什么区别

1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给另一个存储单元.(Java中的存储单元并不是物理内存的地址,但具有相关性)  例如: //定义了一个改变参数值的函数 public static void changeValue(int x) {   x = x *2; } public class TestMain{ //调用该函数 int num = 5; System.out.println(num); changeValue(num); System.out.prin

Java千百问_06数据结构(015)_数组和普通对象的引用变量有什么区别

1.数组和普通对象的引用变量有什么区别 了解什么是数组看这里:java中的数组是什么  对于Java的数组来说,只有类型兼容(即属于同一数据类型体系且遵守优先级由低到高原则),才能将数组引用传递给另一数组引用,但仍然不能改变数组长度(仅仅只是调整数组引用指针的指向).  了解数组传递看这里:数组如何传递 public class TestArrayLength { public static void main(String[] args) { int[] numbers = { 3, 5, 1

Java千百问_05面向对象(005)_接口和抽象类有什么区别

1.接口和抽象类有什么区别 在Java语言中,抽象类abstract class和接口interface是抽象定义的两种机制. 正是由于这两种机制的存在,才赋予了Java强大的面向对象能力.抽象类abstract class和接口interface在对于抽象定义方面具有很大的相似性,甚至可以相互替换.因此很多开发者在进行抽象定义时对二者的选择显得比较随意.其实,两者之间还是有很大的区别,对于它们的选择能反映出对问题本质的理解.对设计意图的理解. 了解抽象类看这里:java中抽象概念如何体现的 

Java 接口和抽象类区别

1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了.当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 .面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点. 既然面向对象设计的重点在于