Scala学习——类

简单类和无参方法

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

  

Scala中的类不声明为public,一个Scala源文件中可以有多个类。

 
val myCounter = new Counter // 或new Counter()
myCounter.increment()

  

调用无参方法时,圆括号是可写可不写的。推荐的做法是:如果是会改变对象状态的方法,就带上( );否则,就不带。

如果将方法的声明改为以下形式,那么可以强制不能带( )(下面要提到的getter就是这种风格的,所以调用getter时,必须不带( )):

class Counter {
private var value = 0 // 必须初始化字段
def increment() { value += 1 } // 方法默认公有
def current = value // 调用必须是myCounter.current这种风格
}

  

带getter和setter的属性

在Java中,通常将字段声明为私有的,然后添加公有的getter和setter方法来提供访问字段的接口。像这样拥有一对getter/setter的字段,通常被称为属性(property)。

Scala对每个字段都提供了getter和setter方法。

class Person {
var age = 0
}

  

在面向JVM的类中,这个简单的Person类有一个私有的age字段和相应的,公有的getter和setter方法。(如果将age声明为private的,getter和setter方法也是私有的。)Scala中,getter和setter分别叫做age和age_=。

println(fred.age) // 调用方法fred.age()
fred.age = 21 // 调用方法fred.age_=(21)

  

将这个简单的Person编译后,使用javap查看生成的字节码,可以验证这一点。

 
// -private选项说明显示所有的类和成员
javap -private Person.class

  

public class Person implements scala.ScalaObject {
private int age;
public int age();
public void age_$eq(int); // =号被翻译成了$eq
public Person();
}

  

知道了这些默认实现后,就可以使用自己的实现来代替默认实现了。

class Person {
private var privateAge = 0 def age = privateAge
def age_=(newValue: Int) {
if (newValue > privateAge) privateAge = newValue
}
}

  

Scala中,字段和getter/setter间的关系,还有其他几种情况。

使用val声明的字段,是只有getter,因为val声明的是不可变的啊。Scala中不能实现只有setter的字段。

还有种对象私有字段。Scala中,方法可以访问该类的所有对象的私有字段,这一点与Java一样。如果通过private[this]来字段来修饰,那么这个字段是对象私有的,这种情况下,不会生成getter和setter。对象私有字段,只能由当前对象的方法访问,而该类的其他对象的方法是无法访问的。如果说分不清楚对象和类的区别,这里就又要犯浑了。

接下来是一种与private[this]相似的访问控制。Scala中可以使用private[class-name]来指定可以访问该字段的类,class-name必须是当前定义的类,或者是当前定义的类的外部类。这种情况会生成getter和setter方法。

Bean属性(L1)

使用 @BeanProperty注解来为字段生成符合JavaBeans规范的getter/setter方法。使用该注解后,将会生成4个方法:Scala的getter/setter和JavaBeans规范的getter/setter(如果是val声明,就没有setter部分了)。

import scala.reflect.BeanProperty
// 在Scala 2.10.0之后已被废弃
// 使用scala.beans.BeanProperty代替
class Person {
@BeanProperty var name: String = _
}

  

构造器(Constructor)

在Scala中,有两种构造器,主构造器(primary constructor)和辅助构造器(auxiliary constructor)。

辅助构造器

首先来讨论辅助构造器,因为比主构造器更容易理解。辅助构造器与Java构造器很相似,但有两点不同:

  • 名字是this(Java中构造器名称与类名相同)
  • 辅助构造器必须以对已经定义的辅助构造器或主构造器的调用开始
class Person {
private var name = ""
private var age = 0 def this(name: String) {
this() // 调用主构造器
this.name = name
} def this(name: String, age: Int) {
this(name) // 调用辅助构造器
this.age = age
}
}

  

val p1 = new Person // 主构造器
val p2 = new Person("Fred") // 第一个辅助构造器
val p3 = new Person("Fred", 42) // 第二个辅助构造器

  

主构造器

Scala中每个类都有主构造器,并且是与类定义混合在一起的。

主构造器的参数,是类名后()内的内容。

class Person(val name: String, val age: Int) {
// val name: String, val age: Int 部分就是主构造器的参数
}

  

定义如上一个简单类,然后创建一个Person的对象,结果如下:

 
scala> val fred = new Person
0
1
2
fred: Person = Person@2c332d2a

  

也就是说,主构造器会将类定义内的,也就是{ }内的,所有语句执行一次。

如果主构造器参数不带val或var,那么会根据是否被方法使用来决定。如果不带val或var的参数被方法使用了,它会变为对象私有字段;如果没有被方法使用,则被当成一个普通的参数,不升级成字段。

主构造器或许不太好理解。Martin Odersky建议如此看主构造器:Scala中的类也接受参数,像方法一样。

可以将主构造器变为私有的,将private关键字放在圆括号前:

 
 
fRom: http://nerd-is.in/2013-08/scala-learning-classes/

Scala基础入门-4的更多相关文章

  1. Scala 基础入门【翻译】

    原文地址 本文只是带你进入 Scala 的世界,包括安装.不可变量 val.可变量 var.定义类.集合(包括列表(list).集(set).映射(map))以及集合遍历和集合库(能达到并行/并发效果 ...

  2. Scala基础入门-1

    首先需要Scala开发环境的搭建,网上自己找教程. 声明常量与变量 val foo = 0 // 常量 var bar = 0 // 变量 在Scala中,更加鼓励使用val来进行声明,也就是推荐使用 ...

  3. Scala基础入门-3

    学习Scala——映射和元组 映射和和元组,也就是Maps和Tuples.Map这东西应该都挺明白的,就是键值对的集合.而元组,tuple,这东西并不是每个语言都有(Python中是有的,不过当时学的 ...

  4. Scala基础入门-2

    简单类和无参方法 class Counter { private var value = 0 // 必须初始化字段 def increment() { value += 1 } // 方法默认公有 d ...

  5. Scala基础入门-代码碎片

    import scala.util.control._ import java.util.Date object Test { def main(args: Array[String]) { // v ...

  6. scala基础入门

    1.scala当中申明值和变量 scala当中的变量申明可以使用两种方式,第一种使用val来申明变量.第二种使用var来申明变量. 申明变量语法 val/var 变量名 [:变量类型] = 变量值 其 ...

  7. Scala快速入门 - 基础语法篇

    本篇文章首发于头条号Scala快速入门 - 基础语法篇,欢迎关注我的头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech)获取更多干货,也欢迎关注我的 ...

  8. 【原创 Hadoop&Spark 动手实践 5】Spark 基础入门,集群搭建以及Spark Shell

    Spark 基础入门,集群搭建以及Spark Shell 主要借助Spark基础的PPT,再加上实际的动手操作来加强概念的理解和实践. Spark 安装部署 理论已经了解的差不多了,接下来是实际动手实 ...

  9. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. JSP进阶 之 SimpleTagSupport 开发自定义标签

    绝大部分 Java 领域的 MVC 框架,例如 Struts.Spring MVC.JSF 等,主要由两部分组成:控制器组件和视图组件.其中视图组件主要由大量功能丰富的标签库充当.对于大部分开发者而言 ...

  2. Eclipse编译Arduino程序不能使用串口函数Serial.begin解决办法

    在Arduino官方的编译器当中Serial.begin(9600);初始化语句是可以直接使用的,而到Eclipse当中,同样的语句却不能用了.会出现下面的问题: 显然,这是Eclipse没有找到Se ...

  3. 从汇编看c++内联函数评估求值

    在c++中,一个inline函数实体,在整个class 声明未被完全看到之前,是不会被评估求值的,也就是说,对于类里面内联的成员函数本身的分析,要等到class的声明完全结束之后才开始.下面试c++源 ...

  4. discuz二次开发笔记(三)------discuz的安装步骤

    下载好discuz的安装包后,解压在自己定义的文件夹里面,将upload里面的文件拷贝出来放到和upload同级的地方,然后删除upload文件夹. 打开浏览器,输入你文件夹的地址:如:http:// ...

  5. MySql优化方案

    mysql优化方案总结 u       Mysql数据库的优化技术 对mysql优化时一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索 ...

  6. HTML 5 学习 (1)

    一.HTML的发展 20世纪70年代~80年代之间HTML正式诞生,但是没有一个统一的标准,显示内容比较单一.在netscape上显示的网页可能在ie5中无法正常显示,反之亦然. 1998年,HTML ...

  7. 1001 A + B Problem

    基本输入输出函数 #include <stdio.h> int main(){ int a,b; ){ printf("%d\n",a+b); } ; }

  8. angular 入门教程1

    使用angularjs也有一年之久了.从初识angularjs时的激动和兴奋到现在淡定的使用,这其中也是有不少的心酸(刚用的时候和各种js插件的配合使用快把我弄疯了). 细想起来.用MVVM的这种js ...

  9. ORA-01653:表无法通过64(在表空间USERS中)扩展

    问题描述:oracle插入数据时显示ORA-01653 表无法通过64(在表空间USERS中)扩展 原因:  oracle  表空间满了,需要扩展 截图: 解决方法: 1.首先查下表空间 select ...

  10. IEnumerable

    C#基础之IEnumerable 1.IEnumerable的作用 在使用Linq查询数据时经常以IEnumerable<T>来作为数据查询返回对象,在使用foreach进行遍历时需要该对 ...