zoukankan      html  css  js  c++  java
  • Scala中的嵌套类

      在Scala中,你几乎可以在任何语法结构中内嵌任何语法结构。如在类中可以再定义一个类,这样的类是嵌套类,其他语法结构也是一样。嵌套类类似于Java中的内部类。

    一、嵌套类的使用

      对于Scala来说,成员内部类和静态内部类存在不同的位置中,成员内部类正常的存在于类的成员位置中,而静态内部类因为是静态性质的,所以声明在类对应的伴随对象中。

    使用的案例如下:

    class ScalaOuterClass {
      class ScalaInnerClass { //成员内部类
      }
    }
    object ScalaOuterClass {  //伴生对象
      class ScalaStaticInnerClass { //静态内部类
      }
    }

    1、创建内部类的方法

    object ScalaInnerClass {
      def main(args: Array[String]): Unit = {
    ​
        //创建两个外部类的实例
        val outer1 : ScalaOuterClass = new ScalaOuterClass();
        val outer2 : ScalaOuterClass = new ScalaOuterClass();
    ​
        //在scala中创建成员内部类的语法是:new 对象.内部类
        //默认情况下,内部类实例和外部对象关联
        val inner1 = new outer1.ScalaInnerClass
        val inner2 = new outer2.ScalaInnerClass
    ​
        //创建静态内部类实例
        val staticInnerClass = new ScalaOuterClass.ScalaStaticInnerClass
    ​
      }
    }

    2、访问外部类属性的方法

    (1)外部类名.this.属性名

      可以通过外部类对象访问外部类的属性

    class ScalaOuterClass {
      var name:String = "scott"
      private var sal:Double = 1.2
      class ScalaInnerClass { //成员内部类
        def info()={
          // 内部类如果想要访问外部类的属性,可以通过外部类对象访问。
          // 即访问方式:外部类名.this.属性名
          println("name="+ScalaOuterClass.this.name+"age="+
            ScalaOuterClass.this.sal)
        }
      }
    }
    object ScalaOuterClass {  //伴生对象
      class ScalaStaticInnerClass { //静态内部类
      }
    }

      外部类名.this相当于是这个外部类的一个实例,然后通过“外部类名.this”这个实例对象去访问属性

    (2)外部类名别名.属性名

      内部类如果想要访问外部类的属性,也可以通过外部类别名访问(推荐)

    class ScalaOuterClass {
      myOuter =>  //这样写,你可以理解成这样写,myOuter就是代表外部类的一个对象.
      class ScalaInnerClass { //成员内部类
        def info() = {
          println("name = " + ScalaOuterClass.this.name
            + " age =" + ScalaOuterClass.this.sal)
          println("-----------------------------------")
          println("name = " + myOuter.name
            + " age =" + myOuter.sal)
        }}
      // 当给外部指定别名时,需要将外部类的属性放到别名后.
      var name : String = "scott"
      private var sal : Double = 1.2
    }

      外部类名.this 等价 外部类名别名,需要注意的是当给外部指定别名时,需要将外部类的属性放到别名后

    二、类型投影

      首先,展示一段代码中的一个错误:

    class ScalaOuterClass {
      myOuter =>
      class ScalaInnerClass { //成员内部类
        def test(ic:ScalaInnerClass): Unit = {
          System.out.println("使用了类型投影:"+ic)
        }
      }
    object Scala01_class {
      def main(args: Array[String]): Unit = {
        val outer1 : ScalaOuterClass = new ScalaOuterClass();
        val outer2 : ScalaOuterClass = new ScalaOuterClass();
        val inner1 = new outer1.ScalaInnerClass()
        val inner2 = new outer2.ScalaInnerClass()
    ​
        inner1.test(inner1)
        inner1.test(inner2)
        // inner1.test(inner2)
        // error, 需要outer1.ScalanInner而inner2属于outer2.ScalanInner
      }
    }

      在此段代码中,inner1.test(inner2)会发生编译错误,因为在Scala中,内部类实例和外部类的对象是关联的,并不是像Java中那样只看类型,此时inner1中的test方法的参数类型要求的是outer1.ScalaInnerClass。

      Java中的内部类从属于外部类,因此在java中inner.test(inner2) 就可以,因为是按类型来匹配的。

      Scala中内部类从属于外部类的对象,所以外部类的对象不一样,创建出来的内部类也不一样,无法互换使用

      所以为了解决这种问题,那么就引出了类型投影的技术,即在方法声明上,如果使用 外部类#内部类 的方式,表示忽略内部类的对象关系,等同于Java中内部类的语法操作,我们将这种方式称之为类型投影(即:忽略对象的创建方式,只考虑类型)

      将上面的代码中的test方法的参数类型修改为"ic: ScalaOuterClass#ScalaInnerClass",即可解决这样的错误。所以类型投影的作用就是屏蔽外部对象对内部类对象的影响。

     

  • 相关阅读:
    Springboot整合Thymeleaf,Thymeleaf页面引入静态资源
    SpringBoot 使用thymeleaf 跳转页面时,总是提示404找不到页面
    项目报错:jdbcUrl is required with driverClassName.
    Springboot配置拦截器无法跳转登录页面
    查看 SELinux状态及关闭SELinux
    Solaris平台,如何通过端口号快速查看PID(进程)
    getApplicationContext()、getBasecontext()、getApplication() 、getParent()
    android工程下不能运行java main程序的解决办法
    SDCardUtils
    BaseAdapter
  • 原文地址:https://www.cnblogs.com/yxym2016/p/13681433.html
Copyright © 2011-2022 走看看