前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【.Net vs Java? 】 看一看二者的类有多像?

【.Net vs Java? 】 看一看二者的类有多像?

作者头像
FlyLolo
发布2021-10-21 15:49:25
5440
发布2021-10-21 15:49:25
举报
文章被收录于专栏:Core Net

1. 包(Package)、命名空间(NameSpace)

1.1 概念

在Java中常用的是包(Package),较少提到NameSpace的概念。Java官方文档中这样说:

为了使类型更易于查找和使用,避免命名冲突并控制访问,程序员将相关类型的组捆绑到包中。 定义:包是一组提供访问保护和名称空间管理的相关类型。 请注意,类型是指类、接口、枚举和注释类型。 枚举和注解类型分别是特殊类型的类和接口,因此在本课中通常将类型简称为类和接口。

根据这里的概念,Package基本上是对应C#的NameSpace的。

无论是Java还是C#,每个类都有属于一个包/命名空间:

  • Java:
代码语言:javascript
复制
package cn.flylolo.entity;
public class Pig extends Animal{

}
  • C#:
代码语言:javascript
复制
namespace cn.flylolo.entity;
public class Pig : Animal{

}

1.2 命名规则

  • Java一般用域名倒序的方式来作为包名,多个单词用“.”分隔,同时这也对应着目录的层级关系。
  • C#中也可以用这样的规则来命名NameSpace,也见过这样的命名方式,但不强制;并且与目录也可以没有关联关系。

1.3 引用方式

  • Java引用包:
代码语言:javascript
复制
import cn.flylolo.entity.Pig;
  • C# 引用命名空间:
代码语言:javascript
复制
using cn.flylolo.entity.Pig;

C#的命名空间别名:若要引用同名的不同类,处理方式都是写全包/命名空间的名称。C#中觉得较长不美观可以在using的时候设置别名:

代码语言:javascript
复制
using entityPig = cn.flylolo.entity.Pig;

在代码中可以直接使用别名引用。

2.访问修饰符

上一节,Java的包与C#的命名空间类似,但针对访问修饰符,包又与C#的程序集类似。

C#

Java

含义

public

public

相同,访问不受限制。

protected

C#,访问限于包含类或派生自包含类的类型。

private

private

访问限于包含类。

internal或不添加修饰符

不添加修饰符

同一(包/程序集)可访问。

protected internal

protected

相同,访问限于当前(包/程序集)或派生自包含类的类型。

private protected

访问限于包含类或当前程序集中派生自包含类的类型。 自 C# 7.2 之后可用。

3.类与文件

Java中,一个.java文件中,只允许有一个Public的类,并且文件名与此类名一般相同。

C#中则无上述限制。

4.继承,sealed与final

4.1 继承一个类或实现接口:

  • C#用“:" 符号。
  • Java继承类用extends关键字,实现接口用implements关键字。

4.2 不想让一个类被继承:

  • Java 用final关键字:
代码语言:javascript
复制
public final class Shape
  • C# 用sealed关键字:
代码语言:javascript
复制
public sealed class Shape

注意: JDK15的时候,Java也提供了sealed关键字,用于限制继承,例如下列代码

代码语言:javascript
复制
public sealed class Shape permits Circle, Square, Rectangle {
}

通过sealed+permits两个关键字,限制了子类只能是Circle, Square, Rectangle这三个。

5.Static

  • C#,有静态类和静态方法。
  • Java,有静态类和静态方法,但静态类只能是内部类,详见下一节。

6. 内部类、嵌套类

6.1 C#的内部类

C#的内部类比较简单,类似如下代码:

代码语言:javascript
复制
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了。

6.2 Java的内部类

再看一下Java的内部类:

代码语言:javascript
复制
public class OuterClass {
    public String outerClassName = "outerClass's name";

    public void getNestedClassName() {
        String staticString = NestedStaticClass.staticString;
        //无法直接调用非静态内部类的变量
        //String str = NestedClass.nestedClassName;
    }

    public NestedClass getNestedClass() {
        //可以直接new
        return new NestedClass();
    }


    class NestedClass {
        public String nestedClassName = "nestedClass's name";

        public void printOuterClassName() {
            //可以直接调用外部类的对象
            System.out.println(outerClassName);
        }

        public OuterClass getOuter() {
            //返回外部类实例
            return OuterClass.this;
        }
    }

    static class NestedStaticClass {
        public String nestedClassName = "NestedStaticClass's name";
        public static String staticString = "staticString";

        public void printOuterClassName() {
            //error 不可以直接调用外部类的对象
            //System.out.println(outerClassName);
        }

        //error 无法返回外部类实例
//        public OuterClass getOuter(){
//            return OuterClass.this;
//        }
    }
}
class Test{
    public static void main(String[] args) {
        //不允许直接通过new的方式创建OuterClass.NestedClass
        //OuterClass.NestedClass nestedClass1 = new OuterClass.NestedClass();

        //只能通过外部类的实例创建内部类
        OuterClass outerClass = new OuterClass();
        //通过方法返回内部类实例
        OuterClass.NestedClass nestedClass = outerClass.getNestedClass();
        //通过.new关键字
        OuterClass.NestedClass nestedClass1 = outerClass.new NestedClass();

        //通过内部类实例获取外部类实例
        System.out.println(nestedClass1.getOuter().outerClassName);
        nestedClass.printOuterClassName();

        String staticString = OuterClass.NestedStaticClass.staticString;
        OuterClass.NestedStaticClass nestedStaticClass = new OuterClass.NestedStaticClass();
        System.out.println(nestedStaticClass.nestedClassName);

    }
}

可见,Java的内部类“玩法比较多,完全写来下可以说是一个比较大的专题了,简要列举一下与C#的内部类的不同之处。

6.3 非静态内部类总结

  • 外部类都无法访问内部类的的方法和属性,但Java的内部类可以访问外部类的方法和属性,C#的不可以,Java内外部类互相访问提供了“.New”和“.this"关键字。
  • 创建内部类,new的对象不同,C#通过“new 外部类.内部类() ”方式创建,Java不允许这样,需要外部类的实例,即:”外部类实例.new 内部类()“。
  • 除了上述的内部类定义方式,Java的内部类可以出现在外部类的方法、语句块中。

6.4 静态内部类总结

  • C#的静态类中不允许有非静态方法和成员属性,Java的静态内部类中可以有。
  • C#和Java的内部类可以直接通过“外部类.内部类”的方式访问,具体要考虑内部类对应的访问修饰符。
  • C#的内部类不允许被new出新实例,Java的可以。
  • Java通过直接的方式访问内部类,只允许访问静态方法和成员属性。通过new的方式产生的实例,即可以访问静态成员也可以访问非静态成员。但不建议通过这种方式访问静态成员。

6.5 其他

  • Java还可以通过内部类的方式实现匿名类、多重继承等。
  • Java8之后,一些情形可以通过lamda简化内部类的写法。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 包(Package)、命名空间(NameSpace)
    • 1.1 概念
      • 1.2 命名规则
        • 1.3 引用方式
        • 2.访问修饰符
        • 3.类与文件
        • 4.继承,sealed与final
          • 4.1 继承一个类或实现接口:
            • 4.2 不想让一个类被继承:
            • 5.Static
            • 6. 内部类、嵌套类
              • 6.1 C#的内部类
                • 6.2 Java的内部类
                  • 6.3 非静态内部类总结
                    • 6.4 静态内部类总结
                      • 6.5 其他
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档