即,在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”的方式得到。
现在不理解,不要紧,很多的知识点,过一会再去理解,会好很多