scala学习-类与对象
【《快学Scala》笔记】
一、类
1、Scala中的类是公有可见性的,且多个类可以包含在同一个源文件中;
class Counter{
private var value = 0 //类成员变量必须初始化,否则报错 def increment(){ //类中的方法默认是公有可见性
value += 1
} def current() = value //对于类中的“取值方法”,在定义时可省略掉括号,直接 def current = value
}
Scala类的使用:
Scala的类在未提供构造器时,也会提供默认构造器;且在调用无参构造器或无参方法时可省略掉方法后的括号。
2、Scala类的每个字段都有getter和setter方法,私有字段的getter和setter默认是私有的,公有字段的getter和setter方法默认是公有的。
其中对于类中的属性value,Scala类默认生成的getter方法名为 value,默认生成的setter方法名为 value_= 。使用时,我们可以重新定义获取或设置属性的方法。
例如,
class Clock{
var hour = 0
var minute = 0
var second = 0 def getTime():String={
return hour+":"+minute+":"+second
}
}
对于Clock类中的属性,如 hour,其对应的getter方法为 hour ,其对应的setter方法名为 hour_=
【注:可以重新定义获取Scala类中属性的方法,但是最好不要与属性默认对应的getter/setter方法重名,否则会报错。】
3、对于Scala类中的val属性,只有默认的getter方法;对于private属性,其默认getter、setter都是private的。因而,对于不想提供setter方法的变量可以设置为val,对于不想提供getter、setter方法的变量可以设置为private。
4、注意,Scala类中,定义无参函数时,若函数声明时省略了函数名后的括号(由于无参数,可以省略),调用时,必须参数无括号的形式,通过带括号形式调用会报错。如,
class Counter{
var value = 0 def current = value
}
类Counter定义中,对于方法current,由于不接受参数,所以定义时省略了方法名current后的括号。此时,对于Counter的实例counter,调用current方法时,必须采用counter.current(无括号形式)。
5、对于Scala类中定义的字段,在Scala中实际为私有字段。(还有待进一步理解和验证)
class Counter{
var value = 0
val sum = 0
private var cnt = 1 //....
}
在Counter类中,Scala在为Counter生成面向JVM的类时,对于value字段,会生成对应的私有字段value和公有的getter、setter方法;对于sum字段,会生成私有的final字段和公有的getter方法;对于cnt字段,会生成私有字段cnt和私有的getter、setter方法(貌似这个private声明只是影响的Scala根据属性生成的对应getter、setter的可见性)。
6、构造器
Scala的类可以有一个主构造器和多个辅助构造器。每个辅助构造器的名称为this,每一个辅助构造器都必须以调用已经定义的辅助构造器或主构造器开始定义。
- 主构造器
如果一个类没有显示定义主构造器,则有一个默认的无参主构造器。
如定义一个Student类,
class Student(val name:String, var age:Int = 0, address:String = "", private var school:String = ""){
var grade:Int = if( age>7 ) age-7 else 0 println(" I'm in main constructor. ") def info() = " name is "+name+", age is "+age+", address is "+address
}
对于Scala类,主构造器的参数放置在类名后,由括号括起来。且对于主构造器中var、val、private 等标注的参数,都会成为类的对应字段,并生成对应的默认getter、setter方法。如Student类中的name、age、school等。对于主构造器中的未用var、val标注的参数,如果在类的任何一个方法用用到该参数,该参数将会转换为类的字段,否则不会,如Student类的address属性。
由于在Student类中的info方法中用到了参数address,所以Student共有name、age、address、school、grade等5个属性,且Scala根据对应属性的特点生成了默认的getter和setter方法。
对于主构造器的参数,也可以提供参数默认值。通过为主构造器提供默认值可减少辅助构造器的个数。
主构造器的函数体,是类中除了方法定义以外的其他语句,如在Student类的主构造器中,包含grade属性的初始化和prinln这两行语句。
Stuent类的使用。
- 辅助构造器
辅助构造器通过this来定义,且必须首先调用主构造器或者其他已经定义的辅助构造器。
class Person(val name:String){
var age = 0
var sex:Char = 'f' println("main constructor...") def this(name:String, age:Int){
this(name) //调用主构造器
this.age = age //使用this关键字 println(" auxiliary constructor1 ")
} def this(name:String, age:Int, sex:Char){
this(name, age) this.sex = sex println(" auxiliary constructor2 ")
}
}
【注:辅助构造器的参数前不能添加val、var标志,否则会报错。】
- 私有主构造器
class Person private(val name:String){
var age:Int = 1 def this(name: String, age:Int){
this(name)
this.age = age
} }
私有构造器通过在类名后用private关键字标注主构造器参数来标明。此时,可以通过辅助构造器来创建该类的对象。
7、嵌套类
class Family(val h_name:String, val w_name:String){
class Husband(var name:String){
println(" I'm a husband ")
} class Wife(var name:String){
println(" I'm a Wife ")
} var husband = new Husband(h_name)
var wife = new Wife(w_name) def info(){
println( "husband: "+husband.name+", wife:"+wife.name )
}
}
在Scala中,你几乎可以在任何语法结构中嵌套任何语法结构,如在函数中定义函数,在类中定义类。
二、对象(object)
1、Scala中没有静态方法和静态字段,但是可以用object语法来实现类似的功能。对象定义了某个类的单个实例。
Scala的object中可以用来实现类似的功能,用来存放工具函数或常量等。如,
object Sequence{
private var next_num = 0
val threshold = 100 def getSequence() = {
next_num += 1
next_num
}
}
使用object中的常量或方法,通过object名直接调用,对象构造器在对象第一次被使用时调用(如果某对象一直未被使用,那么其构造器也不会被调用)。
object的构造器不接受参数传递。
2、伴生对象
可以将在Java类中定义的静态常量、方法等放置到Scala的类的伴生对象中。伴生对象与类同名,且必须放置在同一源文件中。类可以访问伴生对象私有特性,但是必须通过 伴生对象.属性名 或 伴生对象.方法 调用。
伴生对象是类的一个特殊实例。
class Counter{
def getTotalCounter()= Counter.getCount
} object Counter{
private var cnt = 0 private def getCount()= cnt
}
如在类Counter访问其伴生对象的石油方法getCount,必须通过 Counter.getCount() 的方式调用。
3、对象可以继承或扩展多个特质
abstract class Person(var name:String, var age:Int){
def info():Unit
} object XiaoMing extends Person("XiaoMing", 5){
def info(){
println(" name is "+name+", age is "+age)
}
}
4、apply方法
当遇到 object(参数1, 参数2,....,参数n)的形式的调用时,apply方法便会被调用。
5、main方法——Scala程序的入口
main方法定义在object中,形式如下:
object HelloWorld{
def main(args: Array[String]){
println("Hello World!")
}
}
可以通过scalac 源文件名,然后通过 scala 类名 来执行主程序。
6、还可以通过扩展特质App来运行指定代码
object HelloWorld2 extends App{
println(" A 'Hello world' from HelloWorld2 ")
}
通过扩展App特质的方式执行程序时,将要执行的程序放到了object的主构造器中。
7、枚举
Scala并没有定义枚举类型,但是可以通过定义扩展Enumeration的对象,并用Value方法初始化枚举类中的所有可选值,提供枚举。
object TrafficeLight extends Enumeration{
val Red, Yellow, Green = Value }
上述实例中的val Red, Yellow, Green = Value语句,相当于
val Red = Value
val Yellow = Value
val Green = Value
用Value方法初始化枚举类变量时,Value方法会返回内部类的新实例,且该内部类也叫Value。另外,在调用Value方法时,也可传入ID、名称两参数。如果未指定ID,默认从零开始,后面参数的ID是前一参数ID值加1。如果未指定名称,默认与属性字段同名。
object TrafficLight extends Enumeration{
val Red = Value(1, "Stop")
val Yellow = Value("Wait") //可以单独传名称
val Green = Value(4) //可以单独传ID
}
上例中,Yellow属性就仅定义了名称,Green仅定义ID。
参数在不指定名称时,默认参数的Value为字段名。
【注:枚举类型的值是, 对象名.Value ,如上例中的枚举类型是 TrafficLight.Value。】
8、通过id方法获取枚举类型值的ID
9、通过values方法获取所有枚举值的集合
10、通过ID来获取对应的枚举对象
scala学习-类与对象的更多相关文章
- Scala学习之路 (六)Scala的类、对象、继承、特质
一.类 1.类的定义 scala语言中没有static成员存在,但是scala允许以某种方式去使用static成员这个就是伴生机制,所谓伴生,就是在语言层面上,把static成员和非static成员用 ...
- Scala 编程---类和对象
类是对象的蓝图.一旦你定义了类,你就可以用关键字new从类的蓝图里创建对象.比方说,如果给出了类的定义: class ChecksumAccumulator { // class definition ...
- Scala:类,对象和特征(接口)
http://blog.csdn.net/pipisorry/article/details/52902609 Scala类和对象 类是对象的抽象,而对象是类的具体实例.类是抽象的,不占用内存,而对象 ...
- Java学习——类与对象
在学习面向对象之前首先我们要理解一下几点: 什么是面向对象 对象的概念 类 类与对象的关系/区别 什么是对象的属性 什么是对象的方法 什么是面向对象.对象.类 讲到面向对象就不得提到面向过程,早期的计 ...
- Scala学习——类,继承,接口(中)
基本类的使用:(初) package com.dtspark.scala.basics /** * trait是一个接口 * 接口的第一次继承用extends,多继承时用with * 多继承时,如果这 ...
- DELPHI学习---类和对象(五篇)
Classes and objects(类和对象) 类(或者类类型)定义了一个结构,它包括字段(也称为域).方法和属性:类的实例叫做对象:类的字段.方法和属性被称为它的部件(components)或成 ...
- OC学习--类和对象的关系
1. 如何创建对象 面向对象解决问题的时候必须有对象, 那应该如何创建对象? 以建造汽车为例子来解释: >建造汽车需要造车图纸, 图纸上 清楚的描述出 汽车具备的属性和功能(行为) >属性 ...
- Scala学习笔记——函数式对象
用创建一个函数式对象(类Rational)的过程来说明 类Rational是一种表示有理数(Rational number)的类 package com.scala.first /** * Creat ...
- Scala学习笔记(6)对象
1.单例对象.Scala没有静态方法或字段,可以使用object这个语法结构来达到同样的目的.对象定义了单个实例,包含了你想要的特性. object Accounts{ def newUniqueNu ...
随机推荐
- shell脚本字符串截取的8种方法
假设有变量 var=http://www.aaa.com/123.htm. 1. # 号截取,删除左边字符,保留右边字符. echo ${var#*//} 其中 var 是变量名,# 号是运算符,*/ ...
- sqlserver 关于快照
数据库快照:是数据库某一时间点的视图,快照涉及最初目的是为了报表服务,快照还可以和镜像结合来达到读写分离的目的 数据库快照:是sqlserver数据库的只读静态视图快照的作用:1 提供了一个静态的视图 ...
- eclipse 必备
eclipse编辑器太小 http://jingyan.baidu.com/article/fc07f98974f40c12fee51959.html 新建jsp文件报错 http://ji ...
- JAVA TCP网络编程学习笔记
一.JAVA网络编程概述 网络应用程序,就是在已实现网络互联的不同计算机上运行的应用程序,这些程序之间可以相互交换数据.JAVA是优秀的网络编程语言,Java网络编程的类库位于java.net包中.J ...
- KVC/KVO总结
KVC(键值编码) 动态设置: setValue:属性值 forKey:属性名(用于简单路径) setValue:属性值 forKeyPath:属(用于复合路径,例如Person有一个Account类 ...
- CSS Sprites优点
在分析各个网站的CSS时,我们经常可以看到一些网站有很多的元素共享了一张背景图片,而这张背景图片包含了所有这些元素需要的背景,这种技术就叫做CSS Sprites. 例如淘宝的css sprites ...
- spring aop配置及用例说明(2)
欢迎交流转载:http://www.cnblogs.com/shizhongtao/p/3473362.html 这里先介绍下几个annotation的含义, @Before:表示在切入点之前执行. ...
- java.util.ArrayList源码分析
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...
- thinkphp 前后版本ajaxReturn方法的分别
之前用的是thinkphp2的版本现在改到thinkphp3.2已上的版本,发现ajaxReturn这个方法返回的数据不一样了,现在做下记录 thinkphp2的ajaxReturn的实现原码 pro ...
- html5 的<audio> 音频 audio的“坑”
<audio>标签是html5的一个非常有意义的特性.告别的flash的时代.它的属性有: autoplay:音频就绪后马上播放 controls:出现该属性,向用户显示播放的控件. lo ...