黑猴子的家:Scala 嵌套类

即,在class中,再定义一个class,以此类推。
Java中的内部类从属于外部类。Scala中内部类从属于实例。

1、复习一下Java 的嵌套类

(1)嵌套类,小样demo

class Fruit{
  class Pear{

  }
}

Java 里面能不能实现这样的方法?怎么不能实现,是可以的,内部类嘛,Java内部类有四种,静态内部类、匿名内部类、嵌套内部类、成员内部类

(2)Java 内部类

public class Outter {
    class Inner{
        public void myPrintln(){
            System.out.println("haha");
        }
    }
}

Inner 内部类,属于Outter 类这个对象,所以实例化Inner的话,必须用对象实例化

public class MyMain{
  public static void main(String[] args){
    Outter outter = new Outter();
    Outter.Inner inner = outter.new Inner();
  }
}

Inner 这个类是属于 outter这个对象的,类属于对象,类是这个对象成员

(3)Java 静态内部类

public class Outter{
   static class Inner{
    public void myPrintln(){
      System.out.println(“haha”)
    }
  }
}
public class MyMain{
  public static void main(String[] args){
    Outter outter = new Outter();
    Outter.Inner inner = new Outter.Inner();
  }
}

这个静态的Inner类,是属于所有Outter对象的,所以可以直接通过类名的方式去访问
永远记住,非静态的成员内部类,它是属于外部类对象的

2、局域网互加好友案例

(1)创建一个嵌套类,模拟局域网的聊天的一个场景

import scala.collection.mutable.ArrayBuffer
//嵌套类
class Network {
  clas s Member(val name: String) {
    val contacts = new ArrayBuffer[Member]
  }
  private val members = new ArrayBuffer[Member]
  def join(name: String) = {
    val m = new Member(name)
    members += m
    m
  }
}

尖叫提示:Member类是属于Network类对象的,不是直接属于Network这个类的,那就意味着Member这类的类型,前面还有对象的拼接 new Network.new Member(),所以这里用两个不同的Network对象,去创造两个Member,就意味着,这两个Member的实例化对象也是不一样的,类型是不一样的,往里面添加数据的时候,就没发添加,怎么解决呢? 有两个方法,一个是使用伴生对象,一个是使用类投影

Java 里面默认是投影类型

(2)使用该嵌套类

//创建两个局域网
val chatter1 = new Network
val chatter2 = new Network

//Fred 和 Wilma加入局域网1
val fred = chatter1.join("Fred")
val wilma = chatter1.join("Wilma")

//Barney加入局域网2
val barney = chatter2.join("Barney")

//Fred将同属于局域网1中的Wilma添加为联系人
fred.contacts += wilma
//fred.contacts += barney //这样做是不行的,
//Fred和Barney不属于同一个局域网,
//即,Fred和Barney不是同一个class Member实例化出来的对象

尖叫提示:在Scala中,每个实例都有它自己的Member类,就和他们有自己的members字段一样。也就是说,chatter1.Member和chatter2.Member是不同的两个类。也就是所谓的:路径依赖类型,此处需要详细解释之。如果想让members接受所有实例的Member,一般有两种办法

3、方法一 伴生类对象

(1)将Member作为Network的伴生对象存在
Member 以静态类形式存在,scala没有静态类, 伴生类对象,相当于静态类
创建类

import scala.collection.mutable.ArrayBuffer

// 伴生对象
class Network2 {
  private val members = new ArrayBuffer[Network2.Member]
  def join(name: String) = {
    val m = new Network2.Member(name)
    members += m
    m
  }
  def description = "该局域网中的联系人:" +
    (for (m <- members) yield m.description).mkString(", ")
}

object Network2 {
  class Member(val name: String) {
    val contacts = new ArrayBuffer[Member]
    def description = name + "的联系人:" +
      (for (c <- contacts) yield c.name).mkString(" ")
  }
}

尖叫提示:Member 类放到半身对象中,就代表Member是属于Network这个类的,而不是属于Network类对象的,那么我不管你用哪个Network 对象去创建Member, Member都是一样的,最终都是同一个类型

(2)使用

//创建局域网3
val chatter3 = new Network2
//创建局域网四
val chatter4 = new Network2

//Fred 和 Wilma加入局域网3
val fred2 = chatter3.join("Fred")
val wilma2 = chatter3.join("Wilma")

//Barney加入局域网4
val barney2 = chatter4.join("Barney")

//Fred将同属于局域网3中的Wilma添加为联系人
fred2.contacts += wilma2

//Fred将不同属于局域网3中,属于局域网4中的的barney2添加为联系人
fred2.contacts += barney2

println(chatter3.description)
println(chatter4.description)

println(fred2.description)
println(wilma2.description)
println(barney2.description)

4、方法二 类型投影

(1)使用类型投影,注意留意关键符号:“#”
创建类:

import scala.collection.mutable.ArrayBuffer

//投影
class Network3 {
  class Member(val name: String) {
    val contacts = new ArrayBuffer[Network3#Member]
  }

  private val members = new ArrayBuffer[Member]

  def join(name: String) = {
    val m = new Member(name)
    members += m
    m
  }
}

(2)使用

//创建局域网5
val chatter5 = new Network3
//创建局域网6
val chatter6 = new Network3

//Fred 和 Wilma加入局域网5
val fred3 = chatter5.join("Fred")
val wilma3 = chatter5.join("Wilma")

//Barney加入局域网6
val barney3 = chatter6.join("Barney")

//Fred3将同属于局域网5中的Wilma3添加为联系人
fred3.contacts += wilma3

//Fred将不同属于局域网5中,属于局域网6中的的barney3添加为联系人
fred3.contacts += barney3

尖叫提示:与Java一样,在嵌套类中,如果想得到外部类的实例化对象的引用,可以使用“外部类.this”的方式得到。

现在不理解,不要紧,很多的知识点,过一会再去理解,会好很多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值