本节课的主要内容:
1. scala中的类、object实战详解
2. scala中的抽象类、接口实战详解
Scala中的类和object
Scala是一个面型对象和面向函数式的编程语言,他能很好的适应在大型项目开发中,团队协作的要求。(面向对象语言的特性)以及大型数值计算的要求。(面向函数式编程的特点)
类的定义:
class person {
private var name = “spark”
var age = 0
def sayname() {println(name)}
}
与java不同的是类中的属性必须初始化,例如name属性不初始化,就会报错。而对于age属性我们没有加上private,那么scala解释器会自动为我们生成age的set和get方法并把age属性设置成private,这点与java不同。这样我们就可以在类的外部访问age,但是从运行上讲,我们并不是访问age,因为scala已age设置为私有字段,我们实际是在调用set和get方法。对于val则只有get方法。此外我们还能重新生成get和set方法。
而对于private声明的var name属性,scala则不会为我们自动生成get和set方法,我们需要自己生成get和set方法。例如:
class person {
private var name = “Flink”
def name = this.name
def name_=(newName:String) {
name = newName
println(“Hi ” + name)
}
}
总结:在类外部调用属性的方法:
1如果属性没有private修饰,则可直接访问scala自动生成的set和get方法。
2如果有private修饰,则可编写set和get方法来获得私有属性
3通过update方法来获得。
private[this] 属性
对象私有属性,只能当前对象访问,属于当前对象所有,这个相当重要,这个属性是不能被类的其他对象访问的。例如:
Person{
private[this]var name =”spark”
def sayname() {println(name)}
def sayhello(person1:Person){
println(“holle ” +person1.name )
}
}
Var person1 = newPerson()
Var person2 =new Person()
person1.sayhello(person2) //这个scala时会报错的,因为name属性是对象私有的
类的构造器
Scala的构造器与java不同的是,类的构造器是可以传入参数的,他会变成类的私有字段的。
Class person() {
var name = “Spark”
//定义构造器
def this(name:String){
//调用默认构造器或主构造器
this
this.name
}
}
这里我们定义了一个重载构造器,如果不调用默认构造器就会报错,所以重载构造器最后一定要调用默认构造器。
在类的构造时,除了方法以外,类的其他语句都会被执行,一般可以用于类的初始化。如果不想让用户使用默认构造器时可以使用
Class personprivate(val name: String) {
Var name :String = “spark”
def this(name:String) {
this.name = name;
}
}
这是用户是不能调用默认构造器的。
Object伴生对象
Object类似java中的静态类。第一次使用时才执行,与java不同,它是有自己的构造器且构造器没有参数。
如果有个类和object类名相同,则称这个object类是同名类的伴生对象,同名类是该object类的伴生类;
如
object Person {
privatevar grade = 1
def grade = {
println(grade)
}
}
Class Person {
privatename = ”spark”
defname ={
println(name)
}
}
则object Person就是class Person的伴生对象,class Person是可以访问object的所有属性包括私有字段,但是要加伴生对象的名字,即Person.age.
Object中的半生对象
在大多数情况下,类是有其伴生对象的apply的方法实现的,例如:val array = Array(1,2,3)
又如:
object Person {
privatevar grade = 1
def grade = {
println(grade)
}
def apply() = {
println(“ I am in object apply”)
}
}
Class Person {
privatename = ”spark”
def name ={
println(name)
}
}
val person1 = Person()
执行会输出I am in object apply 并返回一个Person类的对象给变量person。这一点有点像java中的静态工厂方法。
抽象类
spark中抽象类RDD是抽象类。
抽象类的定义,利用abstract关键字,在方法内,不写方法体,则方法为抽象方法,不用加关键字abstract,抽象字段,不给变量赋值,该变量则是抽象字段。抽象类的继承利用关键字extends。在子类中,复写(实现)抽象类的方法(最好加上override)。例如:
abstract classPerson {
var name = “people”
def sayname
}
class maleextends Person {
override var name = “male”
override def sayname {
println(name)
}
}
接口trait
类似与java中的interface,但是比java中的interface要强大的多。
声明方法:
trait 接口名字 {}
接口中定义抽象方法,抽象类和实例类来实现,并且trait中可以有实现了的方法,这点与java不同。
class 类名 extends 接口1 with 接口2 … { }
例如:
tarit logger {
def sayName(name:String)
}
class people extends logger {
var name = “me”
override def sayName(name){
println(name)
}
}
Scala不支持多继承但是可以实现多个trait,trait中大多是抽象方法。