[关闭]
@amoszhou 2014-05-10T07:45:05.000000Z 字数 2471 阅读 1149

类与对象

scala


1.类定义

语法如下,属性必须进行初始化,如果用var来申明,则默认就会提供getter setter

  1. class Person {
  2. var age = 0
  3. var name = ""
  4. }

如果只需要getter方法怎么办列。那就定义成val.

  1. class Person {
  2. val age = 0
  3. var name = ""
  4. }

如上面申明,那age就只有get方法了。一般我们调用无参方法(如getter方法)时,可以不写后面的圆括号,比如
person.name.我们如果要设置name的值,则用person.name("scala")

在scala中,属性的getter setter方法并不是getXxx,setXxx。get方法用属性同名,比如person.age(),但我们通常会去掉后面的(),而set方法则对应age_= 。所以我们可以自己定义getter setter来替换掉不需要编译器自动生成的,无需要其它额外操作,只需要方法名如前面所讲的即可。

另外我们还可以在字段前面加上private public来控制是getter setter方法是private还是public的。

2.构造函数

2.1主构造函数

主构造器的参数是直接放置在类名之名。所以我们之前定义的Person类的主构造器就是无参的。那么现在我们对面的例子进行改版。

  1. class Person(val name:String,val age:Int) {
  2. }

那么现在实例化对象就需要传入name和age了。

主构造器会执行类定义中的所有语句,关于语句(statement)的定义,大家可以google一下,简单的说:就是除掉所有的非方法定义(即除掉def开头的)。所以你在里面写上一个打印语句,那么在构造对象的时候就会打印出来。

同时我们还可以为主构造器的参数指定默认值。比如

  1. class Person(val name:String = "",val age:Int =20) {
  2. }

有一种特殊情况要注意:如果一个参数没有用var,val来定义,但只要他被一个方法使用,他就会自动被提升为属性

2.2辅助构造器

二个注意点:

  1. class Person{
  2. var name = ""
  3. var age = 0
  4. def this(name :String){
  5. this() //调用主构造器
  6. this.name=name
  7. }
  8. def this(name:String, age:Int){
  9. this(name) //调用前一个辅助构建器
  10. this.age = age
  11. }
  12. }

3.嵌套类(内部类)

在scala中,语法比较灵活,你可以在在任何语法结构中嵌套任何语法结构。比如:在赋值语句中用流程控制,函数、在函数中定义函数、在函数中定义类,在类中定义类......

  1. class Network{
  2. class Member(val name:String){
  3. }
  4. }

现在假设有2个Network示例:

  1. val chatter = new Network;
  2. val myFace = new Network;

chatter.MembermyFace.Member是不同的2个类。这点与Java是有本质区别的,我们在内部类可以通过外部类.this访问到外部类的this引用。

4.对象

scala中没有静态方法,静态字段。这个观点在一开始的时候我们讨论过,scala认为这些破坏OO纯粹性的。所以对这些不予以支持。如果要这些,也是可以办到的,那就是object。

  1. object Account{
  2. private var lastNumber = 0;
  3. def newUniqueNumber = {
  4. lastNumber += 1
  5. lastNumber
  6. }
  7. }

object的构造是在他第一次被调用时发生。object 不能提供构造函数

object主要用途:

4.1伴生对象

Java中会碰到一个类,既有实例方法,又有静态方法的情况。那么scala中,就是通过伴生对象办到的。伴生对象即与类名同名的对象。比如我们定义了一个class叫Account。现在我们给他定义一个伴生对象。

  1. object Account{
  2. private var lastNumber = 0;
  3. def newUniqueNumber = {
  4. lastNumber += 1
  5. lastNumber
  6. }
  7. }
  8. class Account{
  9. val id = Account.newUniqueNumber
  10. private var balance = 0.0
  11. def deposit(amount : Double){
  12. balance += amount
  13. }
  14. }

我们还发现,类中可以访问伴生对象的方法。其实类与伴生是可以互访问属性和方法的,包括私有属性和方法,但是必须在同一个源文件中。

4.2 扩展类和特质

一个类可以扩展自类和trait。关于扩展至trait我们在后面再讲。扩展自类,比较常见的是给某一个接口提供一个默认行为。

4.3 apply()方法

我们已经在基础那章讲。通常apply()方法返回的是伴生类的对象。之所以选择用apply()而不用构造器,主要是省去new会方便很多,特别是嵌套结构。比如:
Array(Array(1,2,3),Array(4,5,6,7))
如果用new的话,那看起来会是new Array(new Array(1,2,3),new Array(4,5,6,7))。一对比,优势很明显。用好apply()方法会让你的代码看起来更优雅。

5.App对象

其实在搭建环境那一章我们就见过了。任何一个程序都要从main函数开始,但是这也挺麻烦的,有个更简便的方法。就是extends App。然后object里面的所有语句都会执行了。

6.枚举

定义枚举类型:

  1. object Color extends Enumeration {
  2. val RED = Value(0, "#ff0000")
  3. val GREEN = Value(1, "#00ff00")
  4. val BLUE = Value(2, "#0000ff")
  5. }

枚举的类型是Color.Value,而不是Color。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注