您的位置:首页 > 编程语言 > Java开发

A Comparison of C# and Java(转贴)

2008-06-25 09:21 405 查看
/*

Virtual Methods (and final ones too)

One of the tenets of object oriented programming is polymorphism. Polymorphism enables one to interact with members of a type hierarchy as generic types instead of dealing with specific types. The means of implementing polymorphism typically involves having methods in a base class that may be overidden by derived classes. These methods can be invoked even though the client has a reference to a base class type which points to an object of the derived class. Such methods are bound at runtime instead of being bound during compilation and are typically called virtual methods.

In Java all methods are virtual methods while in C#, as in C++, one must explicitly state which methods one wants to be virtual since by default they are not. To mark a method as virtual in C#, one uses the virtual keyword. Also, implementers of a child class can decide to either explicitly override the virtual method by using the override keyword or explicitly choose not to by using the new keyword instead. By default, in C#, the behavior of methods in a derived class that have the same signature as those in the base class is as if they were declared with the new keyword.

It is possible to mark methods as final in Java which means that the method cannot be overridden by derived classes. In C# this can be done by not marking the method as virtual. The major difference is that in C#, the class can still define the method but the base class version is the one that will be called if the object is used via a base class reference. Java disallows the derived class from containing a method that has the same signature as the final base class method.

Below are examples that show the differences in virtual methods in both languages.

*/

//C# Code

using System;

public class Parent{

public void DoStuff(string str){

Console.WriteLine("In Parent.DoStuff: " + str);

}

}

public class Child: Parent{

public void DoStuff(int n){

Console.WriteLine("In Child.DoStuff: " + n);

}

public void DoStuff(string str){

Console.WriteLine("In Child.DoStuff: " + str);

}

}

public class VirtualTest{

public static void Main(string[] args){

Child ch = new Child();

ch.DoStuff(100);

ch.DoStuff("Test");

((Parent) ch).DoStuff("Second Test");

}

}//VirtualTest

//OUTPUT:

//In Child.DoStuff: 100

//In Child.DoStuff: Test

//In Parent.DoStuff: Second Test

//Java Code

class Parent{

public void DoStuff(String str){

System.out.println("In Parent.DoStuff: " + str);

}

}

class Child extends Parent{

public void DoStuff(int n){

System.out.println("In Child.DoStuff: " + n);

}

public void DoStuff(String str){

System.out.println("In Child.DoStuff: " + str);

}

}

public class VirtualTest{

public static void main(String[] args){

Child ch = new Child();

ch.DoStuff(100);

ch.DoStuff("Test");

((Parent) ch).DoStuff("Second Test");

}

}//VirtualTest

//OUTPUT:

//In Child.DoStuff: 100

//In Child.DoStuff: Test

//In Child.DoStuff: Second Test

/*The C# example can be made to produce the same output as the Java example by marking the DoStuff(string) method in the Parent class as virtual and marking the DoStuff(string) method in the Child class with the override keyword. */

//C# Code

using System;

public class Parent{

public virtual void DoStuff(string str){

Console.WriteLine("In Parent.DoStuff: " + str);

}

}

public class Child: Parent{

public void DoStuff(int n){

Console.WriteLine("In Child.DoStuff: " + n);

}

public override void DoStuff(string str){

Console.WriteLine("In Child.DoStuff: " + str);

}

}

public class VirtualTest{

public static void Main(string[] args){

Child ch = new Child();

ch.DoStuff(100);

ch.DoStuff("Test");

((Parent) ch).DoStuff("Second Test");

}

}//VirtualTest

/*

OUTPUT:

In Child.DoStuff: 100

In Child.DoStuff: Test

In Child.DoStuff: Second Test

*/

/*

The above example can be made to produce the original results by altering the signature of the DoStuff(string) method in the Child class to

public new void DoStuff(string str)

which states that although the DoStuff method is virtual in the base class, the child class would like to treat it as a non-virtual method.

File I/O

Both languages support performing I/O via Stream classes. The examples below copy the contents of a file named "input.txt" to another called "output.txt".

*/

//C# Code

using System;

using System.IO;

public class FileIOTest {

public static void Main(string[] args){

FileStream inputFile  = new FileStream("input.txt", FileMode.Open);

FileStream outputFile = new FileStream("output.txt", FileMode.Open);

StreamReader sr     = new StreamReader(inputFile);

StreamWriter sw     = new StreamWriter(outputFile);

String str;

while((str = sr.ReadLine())!= null)

sw.Write(str);

sr.Close();

sw.Close();

}

}//FileIOTest

//Java Code

import java.io.*;

public class FileIO{

public static void main(String[] args) throws IOException {

File inputFile  = new File("input.txt");

File outputFile = new File("output.txt");

FileReader in     = new FileReader(inputFile);

BufferedReader br = new BufferedReader(in);

FileWriter out    = new FileWriter(outputFile);

BufferedWriter bw = new BufferedWriter(out);

String str;

while((str = br.readLine())!= null)

bw.write(str);

br.close();

bw.close();

}

}//FileIOTest

/*

Object Serialization

Object Persistence also known as Serialization is the ability to read and write objects via a stream such as a file or network socket. Object Persistence is useful in situations where the state of an object must be retained across invocations of a program. Usually in such cases simply storing data in a flat file is insufficient yet using a Database Management System (DBMS) is overkill. Serialization is also useful as a means of transferring the representation of a class in an automatic and fairly seamless manner.

Serializable objects in C# are annotated with the [Serializable] attribute. The [NonSerialized] attribute is used to annote members of a C# class that should not be serialized by the runtime. Such fields are usually calculated or temporary values that have no meaning when saved. C# provides two formats for serializing classes; either as XML or in a binary format, the former is more readable by humans and applications while the latter is more efficient. One can also define custom ways an object is serialized if the standard ways are insufficient by implementing the ISerializable interface.

In Java, serializable objects are those that implement the Serializable interface while the transient keyword is used to mark members of a Java class as ones not to be serialized. By default Java supports serializing objects to a binary format but does provide a way of overriding the standard serialization process. Objects that plan to override default serializations can implement methods with the following signatures

private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;

private void writeObject(java.io.ObjectOutputStream stream) throws IOException

Since the above methods are private there is no interface that can be implemented to indicate that a Java class supports custom serialization using readObject and writeObject. For classes that need publicly accessible methods for custom serialization there exists the java.io.Externalizable interface which specifies the readExternal() and writeExternal() for use in customizing how an object is read and written to a stream.

*/

//C# Code

using System;

using System.IO;

using System.Reflection;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

using System.Runtime.Serialization.Formatters.Soap;

[Serializable]

class SerializeTest{

[NonSerialized]

private int x;

private int y;

public SerializeTest(int a, int b){

x = a;

y = b;

}

public override String ToString(){

return "{x=" + x + ", y=" + y + "}";

}

public static void Main(String[] args){

SerializeTest st = new SerializeTest(66, 61);

Console.WriteLine("Before Binary Write := " + st);

Console.WriteLine("/n Writing SerializeTest object to disk");

Stream output  = File.Create("serialized.bin");

BinaryFormatter bwrite = new BinaryFormatter();

bwrite.Serialize(output, st);

output.Close();

Console.WriteLine("/n Reading SerializeTest object from disk/n");

Stream input  = File.OpenRead("serialized.bin");

BinaryFormatter bread = new BinaryFormatter();

SerializeTest fromdisk = (SerializeTest)bread.Deserialize(input);

input.Close();

/* x will be 0 because it won't be read from disk since non-serialized */

Console.WriteLine("After Binary Read := " + fromdisk);

st = new SerializeTest(19, 99);

Console.WriteLine("/n/nBefore SOAP(XML) Serialization := " + st);

Console.WriteLine("/n Writing SerializeTest object to disk");

output  = File.Create("serialized.xml");

SoapFormatter swrite = new SoapFormatter();

swrite.Serialize(output, st);

output.Close();

Console.WriteLine("/n Reading SerializeTest object from disk/n");

input  = File.OpenRead("serialized.xml");

SoapFormatter sread = new SoapFormatter();

fromdisk = (SerializeTest)sread.Deserialize(input);

input.Close();

/* x will be 0 because it won't be read from disk since non-serialized */

Console.WriteLine("After SOAP(XML) Serialization := " + fromdisk);

Console.WriteLine("/n/nPrinting XML Representation of Object");

XmlDocument doc = new XmlDocument();

doc.Load("serialized.xml");

Console.WriteLine(doc.OuterXml);

}

}

//Java Code

import java.io.*;

class SerializeTest implements Serializable{

transient int x;

private int y;

public SerializeTest(int a, int b){

x = a;

y = b;

}

public String toString(){

return "{x=" + x + ", y=" + y + "}";

}

public static void main(String[] args) throws Exception{

SerializeTest st = new SerializeTest(66, 61);

System.out.println("Before Write := " + st);

System.out.println("/n Writing SerializeTest object to disk");

FileOutputStream out  = new FileOutputStream("serialized.txt");

ObjectOutputStream so = new ObjectOutputStream(out);

so.writeObject(st);

so.flush();

System.out.println("/n Reading SerializeTest object from disk/n");

FileInputStream in     = new FileInputStream("serialized.txt");

ObjectInputStream si   = new ObjectInputStream(in);

SerializeTest fromdisk = (SerializeTest)si.readObject();

/* x will be 0 because it won't be read from disk since transient */

System.out.println("After Read := " + fromdisk);

}

}

/*

Documentation Generation from Source Code Comments

Both C# and Java provide a mechanism for extracting specially formatted comments from source code and placing them in an alternate document. These comments are typically API specifications and are very useful way to provide API documentation to the users of a library. The generated documentation is also useful to share the specifications for an API between designers, developers and QA.

Javadoc is the tool used to extract API documentation from source code. Javadoc generates HTML documentation from the source code comment, an example of which is the Java 2 Platform, Standard Edition API Documentation which was all generated using Javadoc. Javadoc can be used to describe information at the package, class, member and method level. Descriptions of classes and member variables can be provided with the option to add references to other classes, class members and methods.

Javadoc allows one to document the following metadata about a method:

Description of the method.

Exceptions thrown by the method.

Parameters the method accepts

Return type of the method.

Associated methods and members.

Indication as to whether the API has been deprecated or not.

Version of the API the method was first added.

The deprecated information is also used by the compiler which issues a warning if a call to a method marked with the deprecated tag is encountered during compilation.

Javadoc also provides the following information automatically:

Inherited API

List of derived classes

List of implementing classes for interfaces

Serialized form of the class

Alphabetical class listing.

Package hierarchy in a tree format.

Since Javadoc generates HTML documentation, it is valid to use HTML in Javadoc comments. There is support for linking the generated documentation with other generated documentation available over the web. Such linking is useful when one wants readers of the documentation to be able to read the API documentation from the related sources. An example of this is the following generated documentation which contains links to the Java 2 API documentation. If no such linking is specified then the generated documentation contains no links to other API documentation. Below is an example of how Javadoc comments are used

*/

//Java Code

/**

* Calculates the square of a number.

* @param num the number to calculate.

* @return the square of the number.

* @exception NumberTooBigException this occurs if the square of the number

* is too big to be stored in an int.

*/

public static int square(int num) throws NumberTooBigException{}

/*

C# uses XML as the format for the documentation. The generated documentation is an XML file that contains the metadata specified by the user with very little additional information generated automatically. All the C# XML documentation tags have an analogous Javadoc construct while the same cannot be said for the Javadoc tags having C# XML documentation analogs. For instance, the default C# XML documentation does not have analogs to Javadoc's @author, @version, or @deprecated tags although such metadata can be generated by reflecting on the assembly, as Microsoft's documentation build process does. One could also create custom tags that are analogous to the Javadoc tags and more but they would be ignored by standard tools used for handling C# XML documentation including Visual Studio.NET. Also of note is that C#'s XML documentation when generated does not contain metadata about the class such as listings of inherited API, derived classes or implementing interfaces. Here is an example of an XML file generated from C# source code.

The primary benefit of an XML format is that the documentation specification can now be used in many different ways. XSLT stylesheets can then be used to convert the generated documentation to ASCII text, HTML, or Postscript files. Also of note is that the generated documentation can be fed to tools that use it for spec verification or other similar tasks. Below is an example of how C# XML documentation is used.

*/

//C# Code

///<summary>Calculates the square of a number.</summary>

///<param name="num">The number to calculate.</param>

///<return>The square of the number. </return>

///<exception>NumberTooBigException - this occurs if the square of the number is too big to be stored in an int. </exception>

public static int square(int num){}

/*

Multiple Classes in a Single File

Multiple classes can be defined in a single file in both languages with some significant differences. In Java, there can only be one class per source file that has public access and it must have the same name as the source file minus the file extension. C# does not have a restriction on the number of public classes that can exist in a source file and neither is there a requirement for the name of any of the classes in the file to match that of the source file.

Importing Libraries

Using libraries in an application is a two-step process. First the needed libraries must be referenced somewhere in the source file which is done via the using keyword in C# and the import keyword in Java. Secondly, there must be a way to tell the compiler where to find the location of the needed library. Specifying the location of libraries that will be used by a Java program is done using the CLASSPATH environment variable or the -classpath compiler option. Assembly locations are specified with the /r compiler switch in C#.

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: