@amoszhou
2014-05-10T07:45:05.000000Z
字数 2471
阅读 1149
scala
语法如下,属性必须进行初始化,如果用var来申明,则默认就会提供getter setter
class Person {
var age = 0
var name = ""
}
如果只需要getter方法怎么办列。那就定义成val.
class Person {
val age = 0
var name = ""
}
如上面申明,那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的。
主构造器的参数是直接放置在类名之名。所以我们之前定义的Person
类的主构造器就是无参的。那么现在我们对面的例子进行改版。
class Person(val name:String,val age:Int) {
}
那么现在实例化对象就需要传入name和age了。
主构造器会执行类定义中的所有语句,关于语句(statement)的定义,大家可以google一下,简单的说:就是除掉所有的非方法定义(即除掉def开头的)。所以你在里面写上一个打印语句,那么在构造对象的时候就会打印出来。
同时我们还可以为主构造器的参数指定默认值。比如
class Person(val name:String = "",val age:Int =20) {
}
有一种特殊情况要注意:如果一个参数没有用var,val来定义,但只要他被一个方法使用,他就会自动被提升为属性
二个注意点:
class Person{
var name = ""
var age = 0
def this(name :String){
this() //调用主构造器
this.name=name
}
def this(name:String, age:Int){
this(name) //调用前一个辅助构建器
this.age = age
}
}
在scala中,语法比较灵活,你可以在在任何语法结构中嵌套任何语法结构。比如:在赋值语句中用流程控制,函数、在函数中定义函数、在函数中定义类,在类中定义类......
class Network{
class Member(val name:String){
}
}
现在假设有2个Network示例:
val chatter = new Network;
val myFace = new Network;
chatter.Member
和myFace.Member
是不同的2个类。这点与Java是有本质区别的,我们在内部类可以通过外部类.this访问到外部类的this引用。
scala中没有静态方法,静态字段。这个观点在一开始的时候我们讨论过,scala认为这些破坏OO纯粹性的。所以对这些不予以支持。如果要这些,也是可以办到的,那就是object。
object Account{
private var lastNumber = 0;
def newUniqueNumber = {
lastNumber += 1
lastNumber
}
}
object的构造是在他第一次被调用时发生。object 不能提供构造函数
object主要用途:
Java中会碰到一个类,既有实例方法,又有静态方法的情况。那么scala中,就是通过伴生对象办到的。伴生对象即与类名同名的对象。比如我们定义了一个class叫Account
。现在我们给他定义一个伴生对象。
object Account{
private var lastNumber = 0;
def newUniqueNumber = {
lastNumber += 1
lastNumber
}
}
class Account{
val id = Account.newUniqueNumber
private var balance = 0.0
def deposit(amount : Double){
balance += amount
}
}
我们还发现,类中可以访问伴生对象的方法。其实类与伴生是可以互访问属性和方法的,包括私有属性和方法,但是必须在同一个源文件中。
一个类可以扩展自类和trait。关于扩展至trait我们在后面再讲。扩展自类,比较常见的是给某一个接口提供一个默认行为。
我们已经在基础那章讲。通常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()方法会让你的代码看起来更优雅。
其实在搭建环境那一章我们就见过了。任何一个程序都要从main函数开始,但是这也挺麻烦的,有个更简便的方法。就是extends App。然后object里面的所有语句都会执行了。
定义枚举类型:
object Color extends Enumeration {
val RED = Value(0, "#ff0000")
val GREEN = Value(1, "#00ff00")
val BLUE = Value(2, "#0000ff")
}
枚举的类型是Color.Value,而不是Color。