1. 包(Package)、命名空间(NameSpace)
1.1 概念
在Java中常用的是包(Package),较少提到NameSpace的概念。Java官方文档中这样说:
为了使类型更易于查找和使用,避免命名冲突并控制访问,程序员将相关类型的组捆绑到包中。
定义:包是一组提供访问保护和名称空间管理的相关类型。 请注意,类型是指类、接口、枚举和注释类型。 枚举和注解类型分别是特殊类型的类和接口,因此在本课中通常将类型简称为类和接口。
根据这里的概念,Package基本上是对应C#的NameSpace的。
无论是Java还是C#,每个类都有属于一个包/命名空间:
Java:
package cn.flylolo.entity; public class Pig extends Animal{ }
C#:
namespace cn.flylolo.entity; public class Pig : Animal{ }
1.2 命名规则
- Java一般用域名倒序的方式来作为包名,多个单词用“.”分隔,同时这也对应着目录的层级关系。
- C#中也可以用这样的规则来命名NameSpace,也见过这样的命名方式,但不强制;并且与目录也可以没有关联关系。
1.3 引用方式
- Java引用包:
import cn.flylolo.entity.Pig;
1
C# 引用命名空间:
using cn.flylolo.entity.Pig;
1
C#的命名空间别名:若要引用同名的不同类,处理方式都是写全包/命名空间的名称。C#中觉得较长不美观可以在using的时候设置别名:
using entityPig = cn.flylolo.entity.Pig;
1
在代码中可以直接使用别名引用。
2.访问修饰符
上一节,Java的包与C#的命名空间类似,但针对访问修饰符,包又与C#的程序集类似。
3.类与文件
Java中,一个.java文件中,只允许有一个Public的类,并且文件名与此类名一般相同。
C#中则无上述限制。
4.继承,sealed与final
4.1 继承一个类或实现接口:
C#用“:" 符号。
Java继承类用extends关键字,实现接口用implements关键字。
4.2 不想让一个类被继承:
Java 用final关键字:
public final class Shape
1
C# 用sealed关键字:
public sealed class Shape
1
注意: JDK15的时候,Java也提供了sealed关键字,用于限制继承,例如下列代码
public sealed class Shape permits Circle, Square, Rectangle {
}
1
2
通过sealed+permits两个关键字,限制了子类只能是Circle, Square, Rectangle这三个。
5.Static
C#,有静态类和静态方法。
Java,有静态类和静态方法,但静态类只能是内部类,详见下一节。
6. 内部类、嵌套类
6.1 C#的内部类
C#的内部类比较简单,类似如下代码:
namespace cn.flylolo.nestedclass; /** * @author luozhichao * @date 2021/10/15 17:50 */ public class OuterClass { public String outerClassName = "outerClass's name"; public void printNestedClassName() { //无法直接调用内部类的变量 //Console.WriteLine(NestedClass.nestedClassName); Console.WriteLine(NestedStaticClass.nestedClassName); } public class NestedClass { public String nestedClassName = "nestedClass's name"; public void printOuterClassName() { //error 不可以直接调用外部类的对象 //Console.WriteLine(outerClassName); } } public static class NestedStaticClass { public static String nestedClassName = "NestedStaticClass's name"; public static void printOuterClassName() { //error 不可以直接调用外部类的对象 //Console.WriteLine(outerClassName); } } } class Test { public static void main(String[] args) { OuterClass.NestedClass nestedClass = new OuterClass.NestedClass(); //可以直接调用静态内部类的方法。 string str = OuterClass.NestedStaticClass.nestedClassName; } }
代码中做了一些注释,可以看到,对于非静态的内部类,外部类就像给其加了一层“命名空间”,可以通过new OuterClass.NestedClass()的方式进行创建。
对应静态内部类,可以通过OuterClass.NestedStaticClass的方式直接调用其方法和属性,当然这也由对应的访问修饰符决定,例如将NestedStaticClass设置为private,则OuterClass可以直接调用NestedStaticClass,而上例中的Main方法则无法调用NestedStaticClass了。