美文网首页Scala
scala中的内部类

scala中的内部类

作者: high_m | 来源:发表于2017-10-14 15:25 被阅读0次

scala的内部类与java的内部类有些不同,Java中的内部类是包含了它的类的成员,Scala中,内部类的作用域边界就是它的外部类,其实这句话并不是那么容易理解的。本文先介绍一下scala的内部类使用语法,接着翻译一篇文章内部类的使用来深层次分析内部类在两种语言中使用方式的不同。

scala内部类使用语法

下面的代码演示了四种内部类表现形式,以及如何访问内部类。

  • 外部类class - 内部类class
  • 外部类class - 内部对象object
  • 外部对象object - 内部类class
  • 外部对象object - 内部对象object
/**
  * Created by gaosong on 2017-10-13
  */
object InnerClassDriver extends App{
    //调用外部类中的内部类对象
    println(new OuterClass().InnerObject.y)

    //调用外部类中的内部类
    val oc = new OuterClass
    var ic = new oc.InnerClass
    println(ic.x)

    //调用外部对象的内部类
    println((new OuterObject.InnerClass).m)

    //调用外部对象的内部对象
    println(OuterObject.InnerObject.n)

}

class OuterClass{
  class InnerClass{
    var x = 1
  }
  object InnerObject{
    val y = 2
  }
}
object OuterObject{
  class InnerClass{
    var m = 3
  }

  object InnerObject{
    var n = 4
  }
}

scala与java内部类的差别

现在有一个图形类Graph(有一个newNode方法,返回一个Node实例),内部有一个结点类Node(有一个connect(other: Node)方法用于连接另一个结点实例)。其余的细节这里不做说明,用scala语言来表现如下:

class Graph {
  class Node {
    var connectedNodes: List[Node] = Nil
    def connectTo(node: Node) {
      if (connectedNodes.find(node.equals).isEmpty) {
        connectedNodes = node :: connectedNodes
      }
    }
  }
  var nodes: List[Node] = Nil
  def newNode: Node = {
    val res = new Node
    nodes = res :: nodes
    res
  }
}

实际项目中,可能有一个graph实例,其内部有若干个node,且这若干个node部分连接在了一起,代码表现如下:

object GraphTest extends Application {
  val g = new Graph
  val n1 = g.newNode
  val n2 = g.newNode
  val n3 = g.newNode
  n1.connectTo(n2)
  n3.connectTo(n1)
}

下面将更近一步,返回的实例n1,n2等加上具体的类型,代码如下:

object GraphTest extends Application {
  val g: Graph = new Graph
  val n1: g.Node = g.newNode
  val n2: g.Node = g.newNode
  val n3: g.Node = g.newNode
  n1.connectTo(n2)
  n3.connectTo(n1)
}

可以看到n1等实例的类型是以外部类的实例g开头的,好的,我们先记住这个特点,再来看一个非法的代码示例:

object IllegalGraphTest extends Application {
  val g: Graph = new Graph
  val n1: g.Node = g.newNode
  val n2: g.Node = g.newNode
  n1.connectTo(n2)      // legal
  val h: Graph = new Graph
  val n3: h.Node = h.newNode
  n1.connectTo(n3)      // illegal!
}

请记住上面代码的最后一行在java实现中却是合法的,因为n1和n3全是Graph.Node类型 但是在scala中它们的类型是以外部类的实例变量名称为前缀的,在这里是g.Node和h.Node,显然是不同的,所以ConnectTo方法是非法的

另外,如果你想两个不同graph的node能够相互连接,可能你需要对上面的内部类做些修改,如下:

class Graph {
  class Node {
    var connectedNodes: List[Graph#Node] = Nil
    def connectTo(node: Graph#Node) {
      if (connectedNodes.find(node.equals).isEmpty) {
        connectedNodes = node :: connectedNodes
      }
    }
  }
  var nodes: List[Node] = Nil
  def newNode: Node = {
    val res = new Node
    nodes = res :: nodes
    res
  }
}

Node类中connectedNodes变量和connectTo方法的参数都是Graph#Node类型,表明一个Node结点能连接另一个graph的Node结点。于此同时,如果你想放宽限制,Graph类的nodes结点集合可以拥有其他Graph的Node,那么你可能还需要改变nodes变量的类型和newNode方法的类型为Graph#Node

但是在实际情况下,这种情况可能不太常见。

一个graph内部的结点node为什么能够连接其他graph内部的结点node呢?两个graph之间一般情况下是不会产生连接关系的,就好像两张图片的点像素一样不会有关联关系,另外一个图片内的nodes集合中为什么会有其他graph内部的node呢?这也是不太合适的。

相关文章

  • scala中的内部类

    scala的内部类与java的内部类有些不同,Java中的内部类是包含了它的类的成员,Scala中,内部类的作用域...

  • Scala的内部类

    与java中内部类不同的是,Scala里面,内部类是属于对象的

  • Java 中的方法内部类

    Java 中的方法内部类 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内...

  • Java 内部类、静态内部类、方法内部类(未完待续)

    内部类 什么是内部类?内部类其实就是在一个类中创建的类。内部类有四种: 成员内部类 静态内部类 局部内部类 匿名内...

  • scala:内部类

    外部类在内部类使用时可以定义别名 静态内部类通过伴生对象定义

  • 内部类

    成员内部类 局部内部类(定义在方法内和定义在作用域内的类) 匿名内部类

  • java学习笔记(十三)内部类

    1、概述 内部类即在类的内部在创建一个类 分为成员内部类(直接在类中创建) 局部内部类(在成员方法中创建) 匿名内...

  • Scala基础(二)

    匿名内部类// 在Scala中,匿名子类是非常常见,而且非常强大的。Spark的源码中也大量使用了这种匿名子类。/...

  • Java 内部类

    内部类包括成员内部类、方法内部类、*静态内部类、匿名内部类*。 内部类的作用 由于内部类的实现和外部类没有关系,内...

  • 方法内部类

    定义在外部类方法中的内部类,也称局部内部类方法内部类1.定义在方法内部,作用范围也在方法内2.和方法内部成成员使用...

网友评论

    本文标题:scala中的内部类

    本文链接:https://www.haomeiwen.com/subject/lgxtuxtx.html