【C#转Java 01】命名空间和包的异同

  本人长期使用C#,现因课程要求转来学一下Java。大体来看两种语言的相似度是非常之高的,但也有不少关键的差异值得注意。今天开始我会将一些比较关键的异同整理总结成博客发布。
  Java的包和C#的命名空间都是为了实现重用性所采取的访问权限控制机制,可以避免命名冲突,将不同功能的复用代码进行分类。他们的使用方法非常的相近,都可以分为创建和引用两个操作。下文我将讨论包和命名空间的异同

创建包/命名空间

创建命名空间

  在C#中使用namespace和花括号来创建命名空间。示例中的代码创建了命名空间nosloofah.test中的Program类和nosloofah.test.tt中的Tester类。在各命名空间中只能直接访问该命名空间和全局命名空间中的类。
  命名空间的命名与文件夹的层级相似,例如nosloofah.test中的类可以理解为路径"nosloofah/test"下的类,而nosloofah.test.c1则表示的就是"nosloofah/test"路径下"c1"文件夹中的类。正因为有这种层级关系,所以Program类中可以直接通过“c1.Tester”来访问命名空间nosloofah.test.c1下的Tester类。
  虽然可以这样理解,但实际上不同命名空间下的类的文件可以都存在于一个文件夹下;命名空间的层级只是一种逻辑上的结构,不是文件的物理储存位置。这也是为什么在C#的一个文件下可以创建多个不同命名空间下的类。

namespace nosloofah.test
{
    class Program
    {
        public static void Main(string[] args)
        {
            c1.Tester t = new c1.Tester();
        }        
    }
}
namespace nosloofah.test.c1
{
    class Tester
    {
    }
}

  另外命名空间可以是可以嵌套创建的。下方示例代码和上方示例代码等效。

namespace nosloofah.test
{
    class Program
    {
        public static void Main(string[] args)
        {
            c1.Tester t = new c1.Tester();
        }
    }
    namespace c1 //全局命名空间访问需要using nosloofah.test.c1;
    {
        class Tester
        {
        }
    }
}

	1. 同个文件可以有多个命名空间
	2. 命名空间的层级关系与文件储存位置无关
	3. 在某命名空间可以直接访问它的子命名空间
	4. 命名空间可以嵌套

创建包

  在java中使用package将整个文件放入某个包中。下方的代码示例中,示例文件被放入nosloofah.test包,那么它就拥有了对于nosloofah.test包中所有类的访问权限;相应的,只有该包内的文件才有直接访问Tester的权限。
  package语句需要写在文件的最前面,且对整个文件中的内容都生效。这是因为Java的包的层级与真实的文件储存位置有关,包nosloofah.test下的文件必须真的存在于路径"nosloofah/test"之下。这样相比之下,包的层级关系似乎更强,可实际上你并不能像在C#里访问子命名空间那样直接使用"tt.Tester"来访问子包nosloofah.test.tt下的类。

package nosloofah.test;
public class Tester 
{
    public static void main(String[] args)
    {
    }
}
1. 一个文件的所有内容只能在一个包内
2. 包的层级关系与文件储存位置直接相关
3. 在某包不可以直接访问它的子包
4. 同个文件中只能有一个public类,且这个类的命名必须与文件名相同。

引用包/命名空间

引用命名空间

  在C#中使用using关键字来引用命名空间。using只可以用来引用命名空间,不能引用命名空间中某个具体的类;引用命名空间必须写在文件的最前面,对整个文件中的内容都生效。实例程序中,我在另一个文件将类Tester2定义在了nosloofah.test.c2.cc2命名空间中,并在另一个文件中引用了nosloofah.test.c2。
  另外在C#中,可以用来修饰类的访问权限修饰词只有public和internal,这两个修饰词决定的是在其他项目能否访问该类。也就是说在C#的同个项目中,只要有访问某个命名空间的权限,我们就可以访问这个命名空间下的所有类。

using nosloofah.test.c2;
namespace nosloofah.test
{
    class Program
    {
        public static void Main(string[] args)
        {
            c2.cc2.Tester2 t = new c2.cc2.Tester2();
        }
    }
}
namespace nosloofah.test.c1
{
    class Tester
    {
        public static void T()
        {
            c2.cc2.Tester2 t = new c2.cc2.Tester2();
        }
    }
}
	1. using需要写在文件最前面,对整个文件生效
	2. using只能应用命名空间,不能引用具体类
	3. 同项目中,引用某命名空间就代表可以使用该命名空间的所有类
	4. 一个文件中可以有任意数量的public类

引用包

  在java中使用import关键字来引用包。import语句需要写在package语句之后,文件中其他内容之前,同样是对整个文件都生效。示例中我将类Tester2放入包nosloofah.test.c1.cc1。
  import可以引用包中具体的某个类,或者说import只能引用具体的类。示例中"import nosloofah.test.tt.;"的""就代表了包import nosloofah.test.tt下的所有类;将"*"换成具体的类名可以不用将整个包都引入。
  另外java中的类可以用private、default、protected和public来修饰,其中用private和default的类不能被其他文件访问,即便其他文件import了对应的包;而protected修饰的类也只能被不同包的子类访问。在一个java文件中只能有一个public类,且这个类必须与文件名同名。

package nosloofah.test;
import nosloofah.test.c1.cc1.*;
public class Tester {
    public static void main(String[] args)
    {
        Tester2 t = new Tester2();
    }
}
	1. import语句必须写在package语句之后,文件其他内容之前,对整个文件生效
	2. import可以用来引用具体某个类
	3. 引用某包的文件只能随意访问包中的public类和protected父类
	4. 一个文件只能有一个public类,且类名必须与文件名相同
posted @ 2023-02-22 20:41  NoSLoofah  阅读(246)  评论(0)    收藏  举报