Scala系列:类

简单类和无参方法:

1 class Counter {
2   private var value = 0; //必须初始化字段
3   def increment() = value += 1 //方法默认是公有的
4   def current = value
5 }

使用:

1 val counter1 = new Counter // 或 new Counter()
2     // 类定义方法是带了(),调用时可带,也可不带
3     counter1.increment
4     counter1.increment()
5     println(counter1.current)
6     println(counter1.current()) // error: 类定义方法时没带(),调用时也不能带

推荐的风格是:改值的方法带();取值的方法不带(),定义时不带便可强制取值风格。

Setter和Getter

1 class Person {
2   var age = 0;
3 }

对于属性age隐式的生成了age()和age_=(age: Int)方法。如果属性带private,则生成的方法也带private;如果属性不带private,则生成的方法为public。
如果属性为val,则只生成get方法。
如果禁用生成隐式的方法,使用private[this]声明。这样只能访问实例自身的属性,不能访问其它实例的属性,即对象私有成员。

注:不能实现只有Setter,没有Getter的属性。想实现,只能用其它名称了。

显式定义age()和age_=(age: Int)方法:

1 class Person {
2   private var _age = 0; // 变成私有并改名
3
4   def age = this._age;
5   def age_=(_age: Int) {
6     this._age = _age;
7   }
8 }

生成的java代码实际上生成了四个方法:显式定义的两个,改名后变量隐式生成的(private)

为什么要改名?不改名无法区分方法名和属性名,而且出现方法定义两次错误

Java Bean规范

生成类似Java Bean的setAge和getAge方法,只需要添加一个注解:@BeanProperty

1 class Person {
2   @BeanProperty
3   var age = 0;
4 }

上面的例子除了隐式生成了age()和age_=(age:Int)方法外,另外生成Java Bean风格的getAge()和setAge(age:Int)方法

主构造方法:

和类定义交织在一起:

  参数被编译成字体;
  主构造方法会执行类定义中的所有语句;
  构造方法中参数不带val也不带var,只有被一个以上方法调用时才会提升为字段。类似于private[this] val效果

1 class Person(@BeanProperty var age: Int) {
2 }

会生成一个带age:Int参数的构造函数;
age()和age_=(age:Int)方法
getAge()和setAge(age:Int)方法

一个类如果没有显式定义主构造方法,会隐式生成一个无参不做任何操作的主构造方法。

辅助构造方法:

辅助构造方法的名称为this;
辅助构造方法每一行必须是调用构造方法(主构造方法或其它辅助构造方法)

def this(age:Int) {
  this()
  _age = age
}

嵌套类:

内部类与外部类实例相关联

 1 class Network {
 2   class Member(val name: String) {
 3     val contacts = new ArrayBuffer[Member]
 4   }
 5   private val members = new ArrayBuffer[Member]
 6   def join(name: String) = {
 7     val m = new Member(name)
 8     members += m
 9     m
10   }
11 }

使用:

1     val chatter = new Network
2     val myFace = new Network
3     val fred = chatter.join("fred")
4     val wilma = chatter.join("wilma")
5     fred.contacts += wilma
6     val ngy = myFace.join("hongdao");
7     fred.contacts += ngy; // error

解析:

  val fred和wilma的类型为chatter.Member;ngy的类型为myFace.Memeber;fred.contacts的实际类型为ArrayBuffer[chatter.Member];
  所以fred.contacts可以添加wilma,不可以添加ngy。

如果不希望这个效果,可以使用两种方式:

方式一:伴生对象

 1 class Network {
 2   private val members = new ArrayBuffer[Network.Member]
 3   def join(name: String) = {
 4     val m = new Network.Member(name)
 5     members += m
 6     m
 7   }
 8 }
 9 object Network {
10   class Member(val name: String) {
11     val contacts = new ArrayBuffer[Member]
12   }
13 }

方式二:类型投影 Network#Member

任何Network的Member

 1 import scala.collection.mutable.ArrayBuffer
 2
 3 class Network {
 4   class Member(val name: String) {
 5     val contacts = new ArrayBuffer[Network#Member]
 6   }
 7   private val members = new ArrayBuffer[Network#Member]
 8   def join(name: String) = {
 9     val m = new Member(name)
10     members += m
11     m
12   }
13 }

内部类访问外部实例:

  外部类.this
  外部类实例别名

1 class Network(val name: String) { outter => //外部类实例别名
2   class Member(val name: String) {
3     val contacts = new ArrayBuffer[Network#Member]
4     def out = println(Network.this.name)
5     def out2 = println(outter.name)
6   }
7 }
时间: 2024-10-27 11:15:06

Scala系列:类的相关文章

Scala 系列(八)—— 类和对象

一.初识类和对象 Scala 的类与 Java 的类具有非常多的相似性,示例如下: // 1. 在 scala 中,类不需要用 public 声明,所有的类都具有公共的可见性 class Person { // 2. 声明私有变量,用 var 修饰的变量默认拥有 getter/setter 属性 private var age = 0 // 3.如果声明的变量不需要进行初始赋值,此时 Scala 就无法进行类型推断,所以需要显式指明类型 private var name: String = _

好程序员大数据教程Scala系列之样例类_Option_偏函数

好程序员大数据教程Scala系列之样例类_Option_偏函数,在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None).Some包装了某个值,None表示没有值. object?OptionDemo {??def?main(args: Array[String]) {????val?map = Map("a"?-> 1, "b"?-> 2)????val?v = map.get("b&q

好程序员大数据教程分享Scala系列之模式匹配和样例类

好程序员大数据教程分享Scala系列之模式匹配和样例类1.样例类在Scala中样例类是一中特殊的类,样例类是不可变的,可以通过值进行比较,可用于模式匹配.定义一个样例类:1.构造器中每一个参数都是val,除非显示地声明为var 2.伴生对象提供apply ,让你不使用new关键字就能构造出相应的对象case class Point(x: Int, y: Int)创建样例类对象:val point = Point(1, 2)val anotherPoint = Point(1, 2)val yet

好程序员大数据学习路线分享Scala系列之集合操作函数

好程序员大数据学习路线继续为大家分享Scala系列之集合操作函数4.6 集合的重要函数4.6.1sum/max/min/count在序列中查找最大或最小值是一个极常见的需求,如下:val numbers = Seq(11, 2, 5, 1, 6, 3, 9) numbers.max //11 numbers.min //1 更高级的例子,其中包含一个书的序列case class Book(title: String, pages: Int) val books = Seq( Book("Futu

好程序员大数据学习路线分享Scala系列之泛型

好程序员大数据学习路线分享Scala系列之泛型,带有一个或多个类型参数的类是泛型的. 泛型类的定义: //带有类型参数A的类定义class Stack[A] {private var elements: List[A] = Nil//泛型方法def push(x: A) { elements = x :: elements }def peek: A = elements.headdef pop(): A = {val currentTop = peekelements = elements.ta

好程序员大数据教程分享Scala系列之Option_偏函数_String

好程序员大数据教程分享Scala系列之Option_偏函数_StringOption类型在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None).Some包装了某个值,None表示没有值. object OptionDemo {def main(args: Array[String]) {val map = Map("a" -> 1, "b" -> 2)val v = map.get("b

大数据Scala系列之文件以及正则表达式

大数据Scala系列之文件以及正则表达式1 读取行导入scala.io.Source后,即可引用Source中的方法读取文件信息. import scala.io.Sourceobject FileDemo extends App{val source = Source.fromFile("C:/Users/admin/res.txt")//返回一个迭代器val lines = source.getLines()for(i <- lines)println(i)//内容也可以放到

大数据Scala系列之特质

大数据Scala系列之特质,特质的定义除了使用关键字trait之外,与类定义无异. 特质用来在类之间进行接口或者属性的共享.类和对象都可以继承特质,特质不能被实例化,因此也没有参数. 一旦特质被定义了,就可以使用extends或者with在类中混入特质. 1 作为接口使用的特质特质的定义: trait Logger{//这是一个抽象方法,特质中未被实现的方法默认是抽象的,不需要abstract关键字修饰def log(msg:String)} 子类对特质的实现: class ConsoleLog

【Scala】Scala的类层级

Scala的类层级 Scala里,每个类都继承自通用的名为Any的超类.因为所有的类都是Any的子类,所以定义在Any中的方法就是"共同的"方法:它们可以被任何对象调用.Scala还在层级的底端定义了一些类,如Null和Nothing,扮演通用的子类.即,Any是所有其他类的超类,Nothing是所有其他类的子类. Any类 层级的顶端是Any类,定义了下列方法: final def ==(that: Any): Boolean final def !=(that: Any): Boo

scala学习-类与对象

类 / 对象 [<快学Scala>笔记] 一.类 1.Scala中的类是公有可见性的,且多个类可以包含在同一个源文件中: 1 class Counter{ 2 private var value = 0 //类成员变量必须初始化,否则报错 3 4 def increment(){ //类中的方法默认是公有可见性 5 value += 1 6 } 7 8 def current() = value //对于类中的“取值方法”,在定义时可省略掉括号,直接 def current = value 9