知识点:
- 静态代码块只执行一次 。
- kotlin 中每个次构造函数都需要委托给主构造函数,可以直接委托也可以通过其他的构造函数间接委托。
- Java中 构造函数不能被继承,只能被子类调用。如果子类没有用super显示调用则会隐式调用父类构造。如果父类没有构造,则会调用父类默认构造。
1. kotlin中
1.1 在kotlin中执行顺序
- 父类的静态代码块 companion object
- 子类的静态代码块
- 父类的主构造函数
- 按定义顺序执行父类的init初始化块儿和属性初始化器
- 父类的次构造函数
- 子类的主构造函数
- 按定义顺序执行子类的init初始化块儿和属性初始化器
- 子类的次构造函数
1.2 怎样验证呢?
父类
public open class GenerParent(info: String) {
// 有参构造
constructor(info: String, name: String) : this(info) {
println("GenerParent 次构造函数 $name $info ")
}
// 属性初始化器 --- 在这里能输出info的值说明主构造函数已经执行过了
var info: String =
info.also { println("GenerParent 中初始化info:$info") }
// 静态代码
companion object {
val PARNTID = 100001.also { println("GenerParent companion object ") }
}
}
子类,
在KOTLIN中每个次构造函数都需要委托给主构造函数,可以直接委托也可以通过其他的构造函数间接委托。
public class GenerChild(info: String, var name:String) : GenerParent(info, name) {
// 无参构造函数
constructor():this("default info", "default name"){
println("GenerChild 无参的次构造函数")
}
// 有参构造
constructor(info:String, id:Int):this(info, "default-name"){
println("GenerChild 的次构造函数 name ${name}")
}
// 属性和init按定义的顺序执行,在主构造函数之后,次构造函数之前
init {
println("GenerChild 初始化init代码块")
}
// 这个相当于静态代码块,最先执行 --1
companion object {
var CODE:Int = 888.also { println("GenerChild object combine 初始化") }
}
}
fun main(a:Array<String>){
GenerChild("对酒当歌,人生几何。", "曹操")
println("---------------------------------")
GenerChild("譬如朝露,去日苦多。", 1001)
println("---------------------------------")
GenerChild()
}
输出:
GenerParent companion object
GenerChild object combine 初始化
GenerParent 中初始化info:对酒当歌,人生几何。
GenerParent 次构造函数 曹操 对酒当歌,人生几何。
GenerChild 初始化init代码块
---------------------------------
GenerParent 中初始化info:譬如朝露,去日苦多。
GenerParent 次构造函数 default-name 譬如朝露,去日苦多。
GenerChild 初始化init代码块
GenerChild 的次构造函数 name default-name
---------------------------------
GenerParent 中初始化info:default info
GenerParent 次构造函数 default name default info
GenerChild 初始化init代码块
GenerChild 无参的次构造函数
// ---------------------------------------------------------------------
2. Java中
2.1 调用顺序
- 父类中的静态
- 子类中的静态
- 父类构造函数
- 子类构造函数。如果子类中不用super调用父类构造,则它会默认先调用父类构造
2.2 如何验证
父类
public class JavaParent {
JavaParent() {
System.out.println("JavaParent 构造");
}
JavaParent(String info) {
System.out.println("JavaParent 有参构造 " + info);
}
static {
System.out.println("JavaParent 静态代码块");
}
}
子类
// 子类的构造方法中如果不用super调用父类的构造,它会默认调用父类的构造
public class JavaChild extends JavaParent {
JavaChild() {
System.out.println("JavaChild 构造");
}
JavaChild(String info) {
System.out.println("JavaChild 有参构造");
}
static {
System.out.println("JavaChild 静态代码块");
}
}
// 调用
void main(){
new JavaChild()
System.out.println("--------------------------")
new JavaChild("java-info")
}
输出
JavaParent 静态代码块
JavaChild 静态代码块
JavaParent 构造
JavaChild 构造
--------------------------
JavaParent 构造
JavaChild 有参构造
个人学习记录用,有错误请指出 <<<<<