Scala学习笔记

来源:互联网 发布:用intent传递数据 编辑:程序博客网 时间:2024/06/17 23:46

第5章 类a1 51

 

面向对象的知识,我觉得一直是若隐若现的明白

 

类中的字段自动带有 getter setter方法

可以用定制getter、setter替换掉字段定义,而不必修改使用类的客户端"统一访问原则"

@BeanProperty 注解

 

每个类都有一个主要的构造器(构造函数)这个构造器和类定义"交织"在一起

它的参数直接成为类的字段。

主构造器执行类体中所有的语句。

辅助构造器是可选的 this

 

 

5.1 简单类和无参方法51

class Counter{

private var value = 0

def increment() { value += 1 }

}

 

改值器的方法建议后面带()

取值器的方法建议后面不带()

取决于在声明的时候,带没带,如果声明的时候带了() 调用时也需要带上

 

 

5.2 带getter和setter的属性 52

java 套路的 javaBean

public class Person{

private int age;

public int getAge() { return age;}

}

这样一对getter,setter通常被称做属性(property) 我们会说Person类有一个age属性

好处在于它们让你可以从简单的get/set机制出发,并在需要的时候做改进,避免公共属性的问题发生

scala对应的

get()

set_()

例如 声明一个成员时,会自动给我们生成getter setter方法,默认是隐式

class Person{ var age = 0 }

get() = age

set_() = age_

 

例如还可以自己重新定义getter setter

class Person{

private var privateAge = 0

def age = privateAge

def age_ = (newValue: Int) {

if(newValue > privateAge) privateAge = newValue

}

}

val fred = new Person

fred.age = 30

fred.age = 21

println(fred.age) //30 不能变年轻

 

几个注意的地方

如果字段是私有的,则getter和setter方法也是私有的

如果字段是val,则只有getter方法被生成

如果不需要任何getter setter可以将字段声明为 private[this]

 

 

5.3 只带getter的属性55

有时候需要一个只读属性,使用val声明即可,例如

class Message{

val time = new java.util.Date

...

}

这时 time 字段则只有getter方法

如果使用val声明了成员变量,没有setter方法,但是这时又想获得setter类似的功能的话,可以通过某种其他的方式改变,例如

class Counter{

private var value = 0

def increment() { value += 1 }

def current = value

}

 

最终使用var 还是 val 看需求了,一般我们学到的都是建议用val

 

实现属性时有四个选择

1.var foo: scala自动合成一个getter和一个setter

2.val foo: scala自动合成一个getter

3.由你来定义foo 和 foo_= 方法

4.由你来定义方法

 

 

5.4 对象私有字段 56

方法可以访问该类的所有对象的私有字段,例如

class Counter{

private varvalue = 0

def increment() { value += 1 }

def isLess(other: Counter) = value < other.value

}

之所以 other.value是合法的,因为other也同样是Counter对象

 

我们可以加上更严格的访问闲置 private[this]

这样一来,Counter类的方法只能访问到当前对象的value字段,而不能访问同样是Counter类型的其他对象的该字段

这样的访问被称 对象私有的

 

类的私有字段scala会生成getter setter,但对于对象的私有字段scala不会生成getter setter

 

 

5.5 bean属性l1 57

给字段加个 @BeanProperty 会自动生成如下

class Person{

@BeanProperty var name: String = _

}

 

1.name: String

2.name_ = (newValue: String): Unit

3.getName(): String

4.setName(newValue: String): Unit

 

 

5.6 辅助构造器 59

也叫做辅助构造函数

scala有

一个主构造器

多个辅助构造器

 

辅助构造器的名称为this

每一个辅助构造器都必须以一个对先前已定义的 其他辅助构造器 或 主构造器的 调用开始

classPerson{

private varname = ""

private varage = 0

 

//辅助构造器

def this(name:String){

this//调用主构造器

this.name= name

}

//另一个辅助构造器

def this(name:String, age: Int){

this(name)//调用前一个辅助构造器

this.age= age

}

}

 

一个类如果没有显示定义 主构造器 则自动拥有一个无参的主构造器

 

 

5.7 主构造器 60

也叫主构造函数,主构造方法

scala中,每个类都有主构造器,主构造器并不以this方法定义,而是与类定义交织在一起

粗体部分为主构造器

class Person(val name: String, val age: Int){

...

}

 

主构造器会指定类定义中的所有语句

如果类名之后没有参数,则该类具备一个无参主构造器,这样一个构造器仅仅是简单地执行类体中的所有语句而已

 

主构造器同样可以使用各种权限配置 var val private等

 

构造参数也可以是普通的方法参数,不带val 或 var 这样的参数如果处理取决于它在类中中如果被使用(类型推断套路)

如果不带var val的参数至少被一个方法所使用,它将被升格为字段,字段同等于 private[this] val的效果

classPerson(name: String, age: Int) {

defdesc = name + "is " + age

}

 

否则,该参数将不被保存为字段,它仅仅是一个可以被主构造器中的代码访问的普通参数

 

主构造器还不熟悉的时候,可以先从辅助构造器入手,记得在声明第一个辅助构造器时调用this()

不过还是建议先搞搞主构造器,这样就相当于类也可以接受参数,想方法一样使用了

 

把主构造器的参数看作是类参数(不带var val)这样的参数的作用域是覆盖了整个类,因此可以在方法中使用它

这样做了的话编译器会自动将它保存为字段

 

 

5.8 嵌套类l1 63

可以在任何语法结构中内嵌任何语法结构

可以在函数中定义函数

在类中定义类

原创粉丝点击