Scala基础入门-2
简单类和无参方法
- 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时,必须不带( )):
带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属性
使用 @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 部分就是主构造器的参数
- }
主构造器的参数被编译成字段,其值被初始化成构造时传入的参数,可以为这些字段也加上访问控制。
主构造器会执行类定义中的所有语句。
- class Person {
- println(0)
- def printNum(num: Int) { println(num) }
- println(1)
- printNum(2)
- }
scala> val fred = new Person
0
1
2
fred: Person = Person@2c332d2a
也就是说,主构造器会将类定义内的,也就是{ }内的,所有语句执行一次。
如果主构造器参数不带val或var,那么会根据是否被方法使用来决定。如果不带val或var的参数被方法使用了,它会变为对象私有字段;如果没有被方法使用,则被当成一个普通的参数,不升级成字段。
主构造器或许不太好理解。Martin Odersky建议如此看主构造器:Scala中的类也接受参数,像方法一样。
可以将主构造器变为私有的,将private关键字放在圆括号前:
- class Person private(val id: Int) { ... }
嵌套类
在Scala中,几乎可以在任何的语法结构中内嵌任何语法结构。可以类中定义类,也可以在方法中定义方法。
Scala中每个实例都有自己的内部类。参考下面这段代码:
- import scala.collection.mutable.ArrayBuffer
- class Network {
- class Member(val name: String) {
- val contacts = new ArrayBuffer[Member]
- }
- private val members = new ArrayBuffer[Member]
- def join(name: String) = {
- val m = new Member(name)
- member += m
- m
- }
- }
- val chatter = new NetWork
- val myFace = new NetWork
chatter.Member类和myFace.Member类是不同的两个类。这一点与Java是不同的。
由于这一点特征,使得一些地方可能会碰见错误,这时候或许需要调整一下内部类。可以使用的方法有使用伴生对象或者使用类型投影(这里是将内部类中的Member换成NetWork#Member)。
与Java中一样,如果需要在内部类中使用外部类的引用,使用 外部类名.class的语法即可。不过Scala中有一个为这种情况服务的语法:
- class Network(val name: String) { outer =>
- class Member(val name: String) {
- ...
- def description = name + " inside " + outer.name
- }
- }
fRom:http://nerd-is.in/2013-08/scala-learning-classes/
Scala基础入门-2的更多相关文章
- Scala 基础入门【翻译】
原文地址 本文只是带你进入 Scala 的世界,包括安装.不可变量 val.可变量 var.定义类.集合(包括列表(list).集(set).映射(map))以及集合遍历和集合库(能达到并行/并发效果 ...
- Scala基础入门-1
首先需要Scala开发环境的搭建,网上自己找教程. 声明常量与变量 val foo = 0 // 常量 var bar = 0 // 变量 在Scala中,更加鼓励使用val来进行声明,也就是推荐使用 ...
- Scala基础入门-4
Scala学习——类 简单类和无参方法 class Counter { private var value = 0 // 必须初始化字段 def increment() { value += 1 } ...
- Scala基础入门-3
学习Scala——映射和元组 映射和和元组,也就是Maps和Tuples.Map这东西应该都挺明白的,就是键值对的集合.而元组,tuple,这东西并不是每个语言都有(Python中是有的,不过当时学的 ...
- Scala基础入门-代码碎片
import scala.util.control._ import java.util.Date object Test { def main(args: Array[String]) { // v ...
- scala基础入门
1.scala当中申明值和变量 scala当中的变量申明可以使用两种方式,第一种使用val来申明变量.第二种使用var来申明变量. 申明变量语法 val/var 变量名 [:变量类型] = 变量值 其 ...
- Scala快速入门 - 基础语法篇
本篇文章首发于头条号Scala快速入门 - 基础语法篇,欢迎关注我的头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech)获取更多干货,也欢迎关注我的 ...
- 【原创 Hadoop&Spark 动手实践 5】Spark 基础入门,集群搭建以及Spark Shell
Spark 基础入门,集群搭建以及Spark Shell 主要借助Spark基础的PPT,再加上实际的动手操作来加强概念的理解和实践. Spark 安装部署 理论已经了解的差不多了,接下来是实际动手实 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
随机推荐
- ios9基础知识(UI)总结
UIWindow.UILabel.UIColor.UIScreen.UIViewController.UIView.UIControl.UIButton.IBOutlet.IBAction.UISte ...
- stuts1:(Struts)Action类及其相关类
org.apache.struts.action.Action类是Struts的心脏,也是客户请求和业务操作间的桥梁.每个Action类通常设计为代替客户完成某种操作.一旦正确的Action实例确定, ...
- [Linked List]Insertion Sort List
Total Accepted: 59422 Total Submissions: 213019 Difficulty: Medium Sort a linked list using insertio ...
- relativelayout常用属性
===================================================================================== 整理于http://naot ...
- [转载]提升进程权限-OpenProcessToken等函数的用法
GetCurrentProcessID 得到当前进程的ID OpenProcessToken 得到进程的令牌句柄LookupPrivilegeValue 查询进程的权限 AdjustTokenPriv ...
- jdbc之二:DAO模式
详细代码请参见 https://code.csdn.net/jediael_lu/daopattern 1.创建Dao接口. package com.ljh.jasonnews.server.dao; ...
- 碰到这个SB错误,'Taglist: Exuberant ctags (http://ctags.sf.net) not found in PATH. Plugin is not loaded.点办
After launching MacVim you may get this annoying error message:'Taglist: Exuberant ctags (http://cta ...
- 字符排序(hdoj1106)
Problem Description 输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整 ...
- UVA 10943 How do you add?
设函数 f(k)(n); 则: f(1)(n)=1; f(2)(n)=f(1)(0)+f(1)(1)+f(1)(2)+...+f(1)(n); f(3)(n)=f(2)(0)+f(2)(1)+f(2) ...
- MFC 操作控件数据
在MFC中有多种获取控件数据的方法 1.GetWindowText()和SetWindowText()函数 ],ch2[],ch3[]; GetDlgItem(IDC_EDIT1)->Get ...