1.Scala面向对象的构造器
1.1 主构造器和从构造器(辅助构造器)
//主构造器
class ConstructorTest(name:String) {
//主构造器调用
val name1:String=name;
//辅助构造器,也叫从构造器
def this()={
//辅助构造器必须在第一行代码
//直接或者间接的调用主构造器
this("mao")//加载主构造器
println("辅助构造器调用")
}
}
object ConstructorTest{
def main(args: Array[String]): Unit = {
//主构造器
var masterCons=new ConstructorTest("maomao")
println(masterCons.name1)
//辅助构造器
var slaveCons=new ConstructorTest()
println(slaveCons.name1)
}
}
运行效果:
辅助构造器可以进行重载
第二个辅助构造器调用第一个辅助构造器
1.2 主构造器参数
a.如果参数使用val或者var来修饰,那么会将参数作为属性来使用
class ConsParams(var age:Int) {
}
object ConsParams{
def main(args: Array[String]): Unit = {
val consParams = new ConsParams(18)
println(consParams.age)
}
}
b.在样例类中,默认会将参数转换为属性来用,默认修饰为val,如果是var需要手动添加
case class ConsParams(var age:Int,name:String) {
}
object ConsParams{
def main(args: Array[String]): Unit = {
val consParams = new ConsParams(18,"zhangsan")
println(consParams.age)
println(consParams.name)
}
}
运行结果如下:
2.继承
定义一个父类Person05,再定义一个子类Student05,在如下代码中,子类继承的父类的从构造器。
/**
* Scala面向对象继承学习
*/
object InheritTest{
def main(args: Array[String]): Unit = {
val student0 = new Student05("zhangsan")
}
}
class Person05()
{
println("父类构造器")
//使用默认值进行初始化,String类型的为空
var name:String=_
def this(name:String) = {
this()
println("父类的辅助构造器")
this.name=name;
}
}
class Student05(name:String) extends Person05(name :String)
{
println("子类的主构造器")
def this(name:String,age:Int)={
this(name)
println("子类的从构造器")
}
}
要点:
1.子类在继承父类的时候,子类的主构造器的参数要大于或者等于父类构造器的参数
2.scala继承的本质就是:子类继承父类的一个构造器
2.1 抽象属性和方法
a.如果父类为抽象类,那么子类需要将抽象抽象的属性和方法实现,否则子类也需要声明为抽象类
abstract class Person06{
//抽象属性
//抽象属性本质就是不写等号
val name:String
val age:Int
//抽象方法
def sayHi():Unit
}
class Student06 extends Person06{
override val name: String = "李四"
override val age: Int = 18
override def sayHi(): Unit =
{
println("Hi")
}
}
//测试代码
val student01 = new Student06
println(student01.name)
println(student01.age)
println(student01.sayHi())
结果:
b.重写非抽象属性需要用override来修饰,重写抽象方法可以不加override,非抽象方法需要加override
c.子类中调用父类的方法,需要使用super关键字
class TestInherit01 {
}
object TestInherit01{
def main(args: Array[String]): Unit = {
val children0 = new Children01
println(children0.sayHi())
}
}
class Father01()
{
def sayHi()={
println("hello world!")
}
}
class Children01() extends Father01()
{
override def sayHi()={
super.sayHi();
println("子Helloworld")
}
}
d.子类对抽象属性进行重写,父类抽象属性可以使用var来修饰
子类对非抽象属性进行重写,父类非抽象属性只支持val而不支持var
因为var本来就可以对变量值进行修改,重写是无意义的
e.scala中属性和方法都是动态绑定的,而java中只有方法是动态绑定的
即多态:此多态与java中多态不同
当我们在java中使用多态的时候,属性打印的是父类的属性值,方法是子类的,而使用scala完成多态时,属性与方法打印的都是子类的。
class Test_Poly {
}
object Test_Poly{
def main(args: Array[String]): Unit = {
val student0 = new Student08
println(student0.name)
println(student0.sayHi())
}
}
class Person08(){
val name:String ="person"
def sayHi(): Unit = {
println("Hi person")
}
}
class Student08() extends Person08(){
override val name: String = "student"
override def sayHi()={
println("Hi Student")
}
}
运行结果:
2.2 匿名子类
可以使用匿名子类来调用抽象类
class TestNom {
}
object TestNom{
def main(args: Array[String]): Unit = {
val per: Person09 = new Person09 {
override val name: String = "zhangsan"
override def sayHi(): Unit = println("hello")
}
println(per.name)
println(per.sayHi())
}
}
abstract class Person09{
val name:String
def sayHi()
}
运行结果: