Scala面向对象编程
Scala中类和java中的类基本是类似的
Scala中的对象时需要定义的,而java中的对象是通过class new出来的
Scala中的接口是trait,java中的接口是interface
类-class
首先看一下类
Scala中定义类和Java一样,都是使用 class 关键字
和Java一样,使用new关键字创建对象
那下面来看一个具体案例
定义Person类,创建对象并调用其方法
class Person{
var name = "scala"
def sayHello(){
println("Hello,"+name)
}
def getName= name
}
注意:如果在定义方法的时候指定了(),那么在调用的时候()可写可不写,如果在定义方法的时候没指定(),则调用方法时肯定不能带()
scala> val p = new Person()
p: Person = Person@23b8d9f3
scala> p.sayHello()
Hello,scala
scala> p.sayHello
Hello,scala
scala> println(p.getName)
scala
scala> println(p.getName())
:10: error: not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
println(p.getName())
constructor
类创建好了,下面我们来看一下类中的构造函数,
Scala类中的构造函数可以分为主构造函数和辅助构造函数
这两种构造函数有什么区别呢?
主constructor:类似Java的默认构造函数 this()
辅助constructor:类似Java的重载构造函数 this(name,age)
主constructor
那先来看一下主构造函数
Scala的主constructor是与类名放在一起的,与Java不同,Java中的构造函数是写在类内部的
注意:在类中,没有定义在任何方法或者是代码块之中的代码就是主constructor的代码
上代码:
先定义一个Student类
class Student(val name:String,val age:Int){
println("your name is " + name + ", your age is " + age)
}
创建对象
scala> new Student("zs",19)
your name is zs, your age is 19
res8: Student = Student@3134153d
在创建对象的时候,类中的println语句执行了,说明这个语句属于主构造函数中的代码
主constructor中还可以通过使用默认参数,来给参数设置默认值
class Student(val name:String = "jack",val age:Int = 20){
println("your name is " + name + ", your age is " + age)
}
创建对象
scala> new Student()
your name is jack, your age is 20
res10: Student = Student@7ddd84b5
scala> new Student("tom",18)
your name is tom, your age is 18
res11: Student = Student@a09303
辅助constructor
Scala中,可以给类定义多个辅助constructor,类似于java中的构造函数重载
辅助constructor之间可以互相调用,但是第一行必须调用主constructor
来看一个案例:
给学生指定姓名和年龄信息
class Student {
var name = "jack"
var age = 10
def this(name: String) {
this()
this.name = name
}
def this(name: String, age: Int) {
this(name)
this.age = age
}
}
执行
scala> val s = new Student("tom")
s: Student = Student@1a538ed8
scala> val s = new Student("mick",30)
s: Student = Student@319642db
对象-object
在scala中,我们可以直接定义一个object,就像定义class一样。
object:相当于class的单个实例,通常在里面放一些静态的field或者method
object不能定义带参数的constructor,只有空参的constructor
第一次调用object的方法时,会执行object的constructor,也就是执行object内部不在任何方法中的代码,因为它只有空参的构造函数
但是注意,object的constructor的代码只会在他第一次被调用时执行一次,以后再次调用就不会再执行了
object通常用于作为单例模式的实现,或者放class的一些静态成员,比如工具方法
object可以直接使用,不能new
创建一个object,使用object关键字
object Person {
var age = 1
println("this Person object!")
def getAge = age
}
执行,直接通过Object的名称调用属性或者方法即可,类似于Java中的静态类
scala> Person
this Person object!
res18: Person.type = Person$@73e776b7
scala> Person.age
res19: Int = 1
scala> Person.getAge
res20: Int = 1
伴生对象
前面学习了class和object,那下面再来看一个特殊的概念,伴生对象
如果有一个class,还有一个与class同名的object,那么就称这个object是class的 伴生对象 ,class是object的 伴生类
注意:伴生类和伴生对象必须存放在一个.scala文件之中
伴生类和伴生对象最大特点在于可以互相访问private field
创建一个Person object和Person class
object Person {
private val fdNum= 1
def getFdNum = fdNum
}
class Person(val name: String, val age: Int) {
def sayHello = println("Hi, " + name + ",you are " + age + " years old!" + ", and you have " + Person.fdNum+ " friend.")
}
执行
scala> new Person("tom",20).sayHello
Hi, tom,you are 20 years old!, and you have 1 friend.
scala> Person.fdNum
:9: error: value fdNum is not a member of object Person
Person.fdNum
^
scala> Person.getFdNum
res26: Int = 1
apply
apply是object中非常重要的一个特殊方法,通常在伴生对象中实现apply方法,并在其中实现构造伴生类对象的功能
在创建对象的时候,就不需要使用new Class的方式,而是使用Class()的方式,隐式调用伴生对象的apply方法,这样会让对象创建更加简洁
例如:Array的伴生对象的apply方法就实现了接收可变数量的参数,以及会创建一个Array对象
val a = Array(1, 2, 3, 4, 5)
看一下文档
查看Array的源码
从Array object的源码中可以看出来,它里面就是在apply方法内部使用new Array创建的对象
main方法
接下来看一下scala中的main方法
和Java一样,在Scala中如果要运行一个应用程序,必须有一个main方法,作为入口
Scala中的main方法必须定义在object中,格式为def main(args: Array[String])
这就需要在编辑器中操作了,我们可以使用eclipse或者idea,但是eclipse对scala的支持不太好,所以建议使用idea
首先确认一下idea中是否集成了scala语言插件
打开idea,点击configure-->plugins
创建Maven项目并引入依赖
添加sdk
好,idea的scala开发环境配置好了,但是我一般还是喜欢再增加一些配置
目前项目的src目录下有一个java目录,这个目录表示是放java代码的,当然了你在里面写scala代码肯定是没有问题的。
只是针对我这种稍微有点强迫症的用起来就有点别扭了
在实际工作中可能我们一个项目既需要使用到java代码,也需要使用到scala代码,所以最好还是建议把java代码和scala代码分开存放,这样比较清晰
接口-trait
接下来看一个scala中的接口,这个接口也是比较特殊的
Scala中的接口称为trait,trait类似于Java中的interface
在triat中可以定义抽象方法
类可以使用extends 关键字继承trait,无论继承类还是trait统一都是使用extends这个关键字
类继承trait后,必须实现trait中的抽象方法,实现时不需要使用override关键字
scala不支持对类进行多继承,但是支持对trait进行多重继承,使用with关键字即可
/**
* Created by xuwei
*/
object PersonDemo {
def main(args: Array[String]): Unit = {
val p1 = new Person("tom")
val p2 = new Person("jack")
p1.sayHello(p2.name)
p1.makeFriends(p2)
}
}
trait HelloTrait { def sayHello(name: String)}
trait MakeFriendsTrait { def makeFriends(p: Person)}
class Person(val name: String) extends HelloTrait with MakeFriendsTrait {
def sayHello(name: String) = println("Hello, " + name)
def makeFriends(p: Person) = println("Hello, my name is " + name + ", your name is " + p.name)
}