类的定义与调用
在一个scala源文件中,类的定义不需要 使用public,一个源文件可以定义多个类,都是默认public
class Test1 {
private var age = 25//scala中的属性必须初始化
//使用注释@BeanProperty可以自动生成get和set方法,但是属性不能私有化,不常用
@BeanProperty
var name = "张三"
//定义的方法默认是public,没有参数时可以省略括号,省略括号后调用该方法则不能添加括号
def setAge(age:Int): Unit ={
this.age = age
}
def getAge: Int ={
age
}
}
在类中的所有成员都不是静态的,所以在类中无法定义主方法,需要在object对象中的主方法调用该类
在object类中的所有成员都是静态的
object Test2 {
def main(args: Array[String]): Unit = {
//无参的方法在调用时,可以省略括号,但是如果方法定义的时候就没有括号则不可以加括号
val p = new Test1
p.setAge(35)
val age = p.getAge
println(age)
}
}
类中的构造器
class Test3(var name: String) {//主构造器
//在一个类中只能有一个主构造器,可以有若干个辅助构造器
def this(){//辅助构造器
this("张三") //调用主构造器 ,在辅助构造器的第一句话,必须调用该类的主构造器或者其他辅助构造器
}
def this(age:Int){
this()//如果没有指名,那么它调用的是无参的构造器
}
}
使用辅助构造器调用其他构造器时,被调用的构造器必须先定义
在主构造器中定义属性
//相当于在类中定义了这些属性,并且自动生成了相应的get set方法,get:name,set:name_$eq
class Department(var empNo:Int,var name:String,var salary:Double,var departmentName:String) {
def this(empNo:Int){
this(empNo,"无名氏",0,"未定")
}
def this(empNo:Int,name: String){
this(empNo,name,1000,"后勤")
}
def this(){
this(0,null,0,null)
}
def info(): String ={
"编号:"+empNo+";姓名:"+name+";薪水:"+salary+";部门:"+departmentName
}
}
在object对象中调用这些构造器:
object Test4 {
def main(args: Array[String]): Unit = {
val d = new Department(1,"张三",200,"策划部")
val information = d.info()
println(information)
val d1 = new Department(1)
val info = d1.info()
println(info)
val d2 = new Department(1,"李四")
val info1 = d2.info()
println(info1)
val d3 = new Department()
val info2 = d3.info()
println(info2)
}
}
伴生类和伴生对象
定义:如果一个类的名字与一个对象的名字相同,那么这个类就叫做伴生类,这个对象叫做伴生对象
object Point{
}
class Point(a:Int,b:Int){
}
作用:在伴生对象中定义apply方法,可以让我们不用new就能直接构造类的实例,同时在调用apply方法时可以省略apply方法名
object Test6 {
def main(args: Array[String]): Unit = {
val p = Point(3,4)
p.aa()
}
}
object Point{
def apply(a: Int, b: Int): Point = new Point(a, b)
}
class Point(a:Int,b:Int){
def aa(): Unit ={
println(a+"-------------"+b)
}
}
类的继承
object Test7 {
def main(args: Array[String]): Unit = {
val w = new Worker()
w.sleep()
}
}
class Ren{
var age:Int = 15
def sleep(): Unit ={
println("睡觉")
}
}
class Worker extends Ren{//子类的主构造器默认调用的是父类的无参构造器,因为无参构造器没有参数,所以Ren后面的()被省略了,子类的辅助构造器永远无法调用超类的构造器,可以调用子类自己的主构造器
var name = "刘德华"
def eat(): Unit ={
println("吃饭")
}
//重写方法必须加上关键字override
override def sleep(): Unit = {
//调用超类的方法
super.sleep()
println("睡睡")
}
}
final关键字
- final修饰类,类不能被继承
- final修饰方法,方法不能被重写
- final修饰常量,常量不能被改变
- finally为异常捕捉时的出口,用于关闭资源
抽象类
object Test9 {
def main(args: Array[String]): Unit = {
val w = new Wr("张三",20,5500)
println(w.info())
println(w.show())
}
}
//抽象类需要添加abstract
abstract class Pe(var name:String,var age:Int){
//抽象方法:没有方法体的方法,被子类继承后必须重写
def show():String;
def this(){
this("张三",23)
println("空参")
}
def info(): String ={
"姓名:"+name+",年龄:"+age
}
}
class Wr(name: String,age:Int,var salary:Double) extends Pe(name, age){//这边的name和age不用再次定义,因为父类已经定义了,其传过来的值会自动赋值给后面的Pe(name,age)构造器,并且这样声明的子类主构造器不会调用父类的无参构造器,它调用的是Pe(name,age)指定的构造器
override def info(): String = {
super.info()+"薪水:"+salary
}
//重写抽象方法
override def show(): String = {
"haha"
}
}