因为scala底层也是基于jvm,并且来源于java,是纯粹的“面向对象”的语言。java在基本数据类型,null还有静态类不是面向对象;
所以这里我们先回顾下java构造器的特点:
- 1 在java中一个类可以定义多个不同的构造方法,构造方法重载
- 2 如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法,比如Person(){}
- 3 一旦定义了自己的构造方法,默认的构造方法就覆盖了,既不能再使用默认的无参构造器,除非显示的定义一下,Person(){}
与java类似,scala同样可以由任意多个构造方法,支持重载
主辅构造器
先上代码,肝起来!
object Study01 {
def main(args: Array[String]): Unit = {
println(new Person("tom",10))
println(new Person("json"))
}
}
//构造器学习,主构造器,辅助构造器;辅助构造器须显示的调用主构造器
class Person( var name: String, var age: Int) {
println("调用主构造函数")
override def toString: String = {
"name: " + name + "\t age: " + age
}
def this(name:String){
this(name,0)
println("调用辅助构造器")
this.name = name
}
}
这里我们需要注意几点:
- 1 主构造器是跟在类名后面的,类属性默认为val 不可变参数,如果辅助构造器进行重新赋值操作,须声明为var
- 2 调用辅助构造器之前必须先调用主构造器
主构造器私有化:
class Person private ( var name: String, var age: Int)
此时只能调用辅助构造器创建对象!
子类调用父类的主构造器
子类中只有主构造器才能调用父类的主构造器,辅助构造器是不能调用父类的构造器的
object Study01 {
def main(args: Array[String]): Unit = {
val tom = new Emp("tom")
println(tom)
}
}
class Person(var pName: String) {
println("调用父类Person主构造器...")
override def toString: String = {
"Person name: " + pName
}
}
class Emp(var eName: String, var eAge: Int) extends Person(eName) {
println("调用子类Emp的主构造器...")
def this(name: String) {
this(name, 0)
println("调用子类Emp的辅助构造器...")
}
override def toString: String = {
s"eName: ${eName} eAge: ${eAge}"
}
}
输出结果:
调用父类Person主构造器…
调用子类Emp的主构造器…
调用子类Emp的辅助构造器…
eName: tom eAge: 0