Scala(四)-①-面相对象初级
2018-11-14 本文已影响2人
sixleaves
① 构造器
Why
构造器的设计目的是为了用来初始化对象,在Scala中构造器分为主构造器
和辅助构造器
两种,辅助构造器必须调用主构造器来构造对象
,并且必须放在第一行
How
语法
class 类名(形参列表) extends 父类名(父类构造器参数列表){ // 主构造器
// 属性
var 属性名1 : 类型1 = 形参1
var 属性名2 : 类型2 = 形参2
// 辅助构造器
def this(形参列表1) { // 辅助构造器1
}
def this(形参列表2) { // 辅助构造器1
}
}
Demo
object ConstructDemo01 {
def main(args: Array[String]): Unit = {
val stu = new Student("lisi", 25)
stu.print()
}
}
class Student(inName :String, inAge :Int) {
var name : String = inName
var age : Int = inAge
def this() {
this("", 0)
println("this construct")
}
def print(): Unit = {
println(s"name = $name, age = $age")
}
println("main construct")
}
What
Scala的主构造器本质是什么?辅助构造器呢?
如下代码是使用反编译工具得到的代码,可加班Scala底层会生成两个Java类型的构造器分别对应.其本质还是java的构造器.
package com.sweetcs.bigdata.scala.day04.chapter07._01_construct;
import scala.Predef.;
import scala.StringContext;
import scala.reflect.ScalaSignature;
import scala.runtime.BoxesRunTime;
public class Student
{
...省略掉属性,现在只关注构造器
public Student()
{
this("", 0);
Predef..MODULE$.println("this construct");
}
public void print()
{
Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "name = ", ", age = ", "" })).s(Predef..MODULE$.genericWrapArray(new Object[] { name(), BoxesRunTime.boxToInteger(age()) })));
}
public Student(String inName, int inAge)
{
this.name = inName;
this.age = inAge;
Predef..MODULE$.println("main construct");
}
}
Details
- Scala的
构造器
不能直接调用super
.且只有主要构造器能够调用父类构造器. - Scala的主构造器放在
类名之后
,并且如果有继承需在父类之后直接写明要调用的父类构造器
.如果是无参数构造器可以都省略.
class Studentn(name :String ) extends Person(sno :String) {
}
- Scala的
辅助构造器名字都为this
,最终
必须要能``调用到主构造器
.因为需要通过主构造器来调用父类构造器构造初始化父类成员 - 默认的构造器访问权限是public,如果要声明为prive,需要在
构造器前加private()
class Studentn private(name :String ) {
}
② 属性高级
Why
属性高级技术主要是提供更加便捷的创建属性的方式.我们需要了解每一种方式对应生成的是读写属性、还是只读、只写.
How
语法
- Scala可以再构造器中直接生成属性,如果是val修饰生成
只读属性
.如果是var修饰读写属性
- Scala可以使用
@BeanProperty
注解修饰属性,生成复合Bean规范的setter和getter
Demo
/**
* @author sweetcs
*/
object PropertiesAdvance {
def main(args: Array[String]): Unit = {
val w1 = new WorkerOne("lisi")
println(w1.name)
println(w1.inName) // 报错
val w2 = new WorkerTwo("wangwu")
println(w2.name)
println(w2.inName) // val是只读的私有属性
w2.inName = "xxx" // 报错
val w3 = new WorkerThree("xiaoming")
println(w3.name)
println(w3.inName) // var是 可读可写 的私有属性
w3.inName = "xiaoliu"
val w4 = new WorkerFour
w4.setName("lisi")
w4.getName
println(w4.name, w4.getName)
w4.name = "wangwu"
println(w4.name, w4.getName)
}
}
class WorkerOne(inName : String) {
var name = inName
}
class WorkerTwo(val inName : String) {
var name = inName
}
class WorkerThree(var inName : String) {
var name = inName
}
class WorkerFour() { // 自动生成Bean规范的setter和getter,且var name底层原有的set和get还保留
@BeanProperty
var name;
}
What
对应的底层反编译源码就不贴了,感兴趣的可以自己用JD-GUI反编译.
Details
- 使用
@BeanProperty
自动生成Bean规范
的setter
和getter
,且var name底层原有的set和get还保留