0
点赞
收藏
分享

微信扫一扫

ScalaNote13-嵌套类


Intro

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

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

那么如何创建内部类对象呢?看个Demo:

class ScalaOuterClass {
class ScalaInnerClass { //成员内部类
}
}
object ScalaOuterClass { //伴生对象
class ScalaStaticInnerClass { //静态内部类
}
}
// 创建外部类
val outer1 : ScalaOuterClass = new ScalaOuterClass()
val outer2 : ScalaOuterClass = new ScalaOuterClass()
// 创建内部类
val inner1 = new outer1.ScalaInnerClass()
val inner2 = new outer2.ScalaInnerClass()
//创建静态内部类对象
val staticInner = new ScalaOuterClass.ScalaStaticInnerClass()

defined class ScalaOuterClass
defined object ScalaOuterClass
outer1: ScalaOuterClass = ScalaOuterClass@39f042fd
outer2: ScalaOuterClass = ScalaOuterClass@73523062
inner1: outer1.ScalaInnerClass = ScalaOuterClass$ScalaInnerClass@39bd005f
inner2: outer2.ScalaInnerClass = ScalaOuterClass$ScalaInnerClass@278ec3a
staticInner: ScalaOuterClass.ScalaStaticInnerClass = ScalaOuterClass$ScalaStaticInnerClass@3924b122

内部类访问外部类属性

内部类访问外部类的属性有两种方式,先看第一种:

class ScalaOuterClass {
val name="Jack"
private val age = 19
class ScalaInnerClass { //成员内部类
def showMe(){
printf("My name is %s.I am %d years old.",ScalaOuterClass.this.name,ScalaOuterClass.this.age)
}
}
}
val outer1 : ScalaOuterClass = new ScalaOuterClass()
val inner1 = new outer1.ScalaInnerClass()
inner1.showMe()

My name is Jack.I am 19 years old.




defined class ScalaOuterClass
outer1: ScalaOuterClass = ScalaOuterClass@494c9bb3
inner1: outer1.ScalaInnerClass = ScalaOuterClass$ScalaInnerClass@533ec21e
warning: previously defined object ScalaOuterClass is not a companion to class ScalaOuterClass.
Companions must be defined together; you may wish to use :paste mode for this.

第一种方式是在内部类中,通过外部类名.this.属性名的方式调用。还可以外部类名别名.属性名的方式调用。看个Demo:

class ScalaOuterClass {
myOuter =>
val name="Jack"
private val age = 19
class ScalaInnerClass { //成员内部类
def showMe(){
printf("My name is %s.I am %d years old.",myOuter.name,myOuter.age)
}
}
}
val outer1 : ScalaOuterClass = new ScalaOuterClass()
val inner1 = new outer1.ScalaInnerClass()
inner1.showMe()

My name is Jack.I am 19 years old.




defined class ScalaOuterClass
outer1: ScalaOuterClass = ScalaOuterClass@104fdadf
inner1: outer1.ScalaInnerClass = ScalaOuterClass$ScalaInnerClass@42d4fa08
warning: previously defined object ScalaOuterClass is not a companion to class ScalaOuterClass.
Companions must be defined together; you may wish to use :paste mode for this.

类型投影

当我们新建一个内部类的对象时,会先和外部类的实例对象绑定,此时每个不同的内部类对象所属类不完全相同(粗暴的这么理解吧,因为他们对应外部类对象都不一样)。先看个Demo:

class ScalaOuterClass3 {
myOuter =>
class ScalaInnerClass3 { //成员内部类
def test(ic: ScalaInnerClass3): Unit = {
System.out.println(ic)
}
}
}
val outer1 : ScalaOuterClass3 = new ScalaOuterClass3()
val outer2 : ScalaOuterClass3 = new ScalaOuterClass3()
val inner1 = new outer1.ScalaInnerClass3()
val inner2 = new outer2.ScalaInnerClass3()
inner1.test(inner1) // ok, 因为 需要outer1.ScalanInner
inner1.test(inner2) // error, 需要outer1.ScalanInner而实际是outer2.ScalanInner

只需要做一个简单的修改,就可以做所谓的类型投影ic: ScalaOuterClass3#ScalaInnerClass3

class ScalaOuterClass3 {
myOuter =>
class ScalaInnerClass3 { //成员内部类
def test(ic: ScalaOuterClass3#ScalaInnerClass3): Unit = {
System.out.println(ic)
}
}
}
val outer1 : ScalaOuterClass3 = new ScalaOuterClass3()
val outer2 : ScalaOuterClass3 = new ScalaOuterClass3()
val inner1 = new outer1.ScalaInnerClass3()
val inner2 = new outer2.ScalaInnerClass3()
inner1.test(inner1)
inner1.test(inner2)

$line27.$read$$iw$$iw$ScalaOuterClass3$ScalaInnerClass3@6f32ac74
$line27.$read$$iw$$iw$ScalaOuterClass3$ScalaInnerClass3@50973861





defined class ScalaOuterClass3
outer1: ScalaOuterClass3 = ScalaOuterClass3@1eef5be9
outer2: ScalaOuterClass3 = ScalaOuterClass3@23e0008c
inner1: outer1.ScalaInnerClass3 = ScalaOuterClass3$ScalaInnerClass3@6f32ac74
inner2: outer2.ScalaInnerClass3 = ScalaOuterClass3$ScalaInnerClass3@50973861

                                2020-03-08 于南京市栖霞区


举报

相关推荐

0 条评论