类class
Scala中类的定义跟Java很相似,类是由属和方法组成,同样可以使用new的方式创建对象实例,进而调用类中定义好的方法与属性。下面就是一个简单的Scala类
class People {
// 属性的定义: val/var 名称:类型 = 值
var name:String = _ // _ 占位符 前提是一定要明确是什么数据类型
var age:Int = 3
// 私有属性,外部不能直接调用
private var gender = "M"
// 定义方法
def playBasketball(team:String) = {
println(name + " is playing basketball of " + team)
}
def drink() = {
name + " is drinking..."
}
}
# 主方法中调用
def main(args: Array[String]): Unit = {
val people = new People // 实例化一个Class对象
people.name = "周琦" // 为对象赋值
people.age = 30
// people.gender 无法调用
println(people.name + " : " + people.age )
people.playBasketball("China")
println(people.drink())
}
}
但是Scala中类的构造器与Java完全不一样,主要分为主构造器和附属构造器。代码示例如下:
/**
* 主构造器 类名(参数名:参数类型)
* 如果你想在外面调用Person的name和age必须在之前加val或者var,默认是私有的
*/
class Person(val name:String,val age:Int){
println("进入Person主构造器")
var job:String = _ // _ 占位符 前提是一定要明确是什么数据类型
val sex="男"
/**
* 附属构造器的名称 this
* 每个附属构造器的第一行必须调用主构造器或者其他的附属构造器
*/
def this(name:String,age:Int,job:String){
this(name,age)
this.job=job
}
println("执行完Person主构造器")
}
无论你调用哪个构造器来创造类实例,一定会将类从头到尾执行一遍。同样的子类创建时也会执行父类主构造器。
/**
* override是子类重写父类中的属性或者方法的修饰符
* new 子类会调用父类的构造
* 子类构造器只能在父类主构造器上添加属性
*/
class Student(name:String,age:Int,val major:String) extends Person(name,age){
println("进入Student构造器")
override val sex="女"
override def toString: String = {
this.name+"\t"+this.age+"\t"+this.job+"\t"+this.sex+"\t"+this.major
}
println("执行完Student构造器")
}
抽象类
/**
* 抽象类:
* 1) 类中有一个或者多个方法/属性的定义,没有实现
* 2) 抽象类是不能直接new
* 3) 使用时要有完全实现了抽象方法/属性的子类才行
* 4) 子类重写父类方法或者属性时不一定需要override
*/
object AbstractClassApp {
def main(args: Array[String]): Unit = {
val people = new People
people.speak
println(people.sum(1))
}
}
abstract class action {
def speak
val word: String
val a=1
def sum(a:Int)=a+1
}
class People extends action {
def speak: Unit = {
println(word)
}
override val word: String = "hello"
}
对象Object
- Object可以拥有属性和方法,且默认都是"static"类型,可以直接用object名直接调用属性和方法。
- Object里的main函数式应用程序的入口。
伴生对象和伴生类
object ApplyApp {
def main(args: Array[String]): Unit = {
val apply = ApplyTest() //调用得是object的apply
val test = new ApplyTest
test() //调用的是class的apply
}
/**
* object是class的伴生对象
* class是object的伴生类
* 类名()=>object apply
* 对象名()=>class apply
*/
object ApplyTest{
println("进入object ApplyTest")
val name="name"
def test()={
println("test")
}
def apply(): Unit ={
println("object apply")
new ApplyTest
}
println("退出object ApplyTest")
}
class ApplyTest{
def apply(): Unit ={
println("class apply")
}
}
}
Trait
Scala的Trait相当于Java里的Interface,但Trait不仅可以定义函数,还可以有函数体实现。实现关键词是extends,实现多个Trait用with。当extends的多个Trait里有相同函数时,子类必须重写该函数。
- 父trait里无函数体的函数,子类必须override
- 重写父类里有函数体的函数,必须有关键词override
- trait里的变量,都是val类型
- 在trait里定义的的变量,必须是val类型,如果变量没初始化,子类必须override
- 建议看看Spark源码的Logging
case class/case object
- case class必须要有参数列表,case object必须不能加参数列表
- class 和 case class的区别:
case class重写了toString,equals,hashCode
case class默认实现了序列化
case class不用new
object CaseClassApp {
def main(args: Array[String]): Unit = {
println(Dog("旺财").name)
}
}
case class Dog(name:String)