3131and first-class delegation`等实现
3232- ` Kotlin ` 可与` Java ` 语言无缝通信。这意味着我们可以在` Kotlin ` 代码中使用任何已有的` Java ` 库;同样的` Kotlin ` 代码还可以为` Java ` 代码所用
3333- ` Kotlin ` 在代码中很少需要在代码中指定类型,因为编译器可以在绝大多数情况下推断出变量或是函数返回值的类型。这样就能获得两个好处:简洁与安全
34- - Kotlin 是一种静态类型的语言。这意味着,类型将在编译时解析且从不改变
34+ - ` Kotlin ` 是一种静态类型的语言。这意味着,类型将在编译时解析且从不改变
3535
3636
3737## ` Kotlin ` 优势
@@ -195,13 +195,13 @@ var weight = 70.5 // double
195195 val bitwiseAnd = FLAG1 and FLAG2
196196 ```
197197
198- - 一个` String ` 可以像数组那样访问,并且被迭代 :
198+ - 一个` String ` 可以像数组那样访问,并且也可以被迭代 :
199199 ```kotlin
200200 var s = "charon"
201201 var c = s[2]
202202
203203 for (a in s) {
204- Log.e("@@@", a +"");
204+ Log.e("@@@", a + "");
205205 }
206206 ```
207207
@@ -263,11 +263,11 @@ class MainActivity : AppCompatActivity() {
263263}
264264```
265265
266- ## 后端变量` Backing Fields ` .
266+ ## 后端变量` Backing Fields `
267267
268268` Kotlin ` 会默认创建` set get ` 方法,我们也可以自定义` get set ` 方法:
269269
270- 在` kotlin ` 的` getter ` 和` setter ` 是不允许本身的局部变量的 ,因为属性的调用也是对` get ` 的调用,因此会产生递归,造成内存溢出。
270+ 在` kotlin ` 的` getter ` 和` setter ` 是不允许调用本身的局部变量的 ,因为属性的调用也是对` get ` 的调用,因此会产生递归,造成内存溢出。
271271
272272例如:
273273
@@ -319,7 +319,7 @@ var myProperty: String
319319## 延迟初始化
320320
321321我们说过,在类内声明的属性必须初始化,如果设置非` null ` 的属性,应该将此属性在构造器内进行初始化。
322- 假如想在类内声明一个` null ` 属性,在需要时再进行初始化(最典型的就是懒汉式单例模式),与 ` Kotlin ` 的规则是相背的,此时我们可以声明一个属性并延迟其初始化,此属性用` lateinit ` 修饰符修饰。
322+ 假如想在类内声明一个` null ` 属性,在需要时再进行初始化(最典型的就是懒汉式单例模式),这就与 ` Kotlin ` 的规则是相背的,此时我们可以声明一个属性并延迟其初始化,此属性用` lateinit ` 修饰符修饰。
323323
324324``` kotlin
325325class MainActivity : AppCompatActivity () {
@@ -400,7 +400,7 @@ val sex: String by lazy(LazyThreadSafetyMode.NONE) {
400400
401401## 类的定义:使用` class ` 关键字
402402
403- 当你在定义类的时候,你需要想想该类所创建的对象需要什么。你需要考虑 :
403+ 当你在定义类的时候,需要想想该类所创建的对象需要什么 :
404404
405405- 每个对象自身的特点
406406
@@ -456,7 +456,7 @@ val myDog = Dog("Fido", 70, "Mixed" )
456456
457457![ Image] ( https://raw.githubusercontent.com/CharonChui/Pictures/master/kotlin_class_dog.jpg?raw=true )
458458
459- 类中所定义的函数又称为成员函数。 有时也被称为方法。
459+ 类中所定义的函数又称为成员函数, 有时也被称为方法。
460460
461461#### 创建对象的执行过程
462462
@@ -587,7 +587,7 @@ class Bird (weight: Double = 0.00, age: Int = 0, color: String = "blue"){
587587Kotlin引入了一种叫作init语句块的语法,它属于上述构造方法的一部分,两者在表现形式上却是分离的。Bird类的构造方法在类的外部,它只能对参数进行赋值。如果我们需要在初始化时进行其他的额外操作,那么我们就可以使用init语句块来执行。比如:
588588
589589``` kotlin
590- class Bird (weight : Double , aget : Int , color : String ) {
590+ class Bird (weight : Double , age : Int , color : String ) {
591591 init {
592592 println (" the weight is ${weight} " )
593593 }
@@ -611,16 +611,14 @@ class Bird(weight: Double, aget: Int, color: String) {
611611 val weight: Double
612612 val age: Int
613613 val color: String
614+ init {
615+ this .weight = weight
616+ this .age = age
617+ }
618+ init {
619+ this .color = color
620+ }
614621}
615-
616- init {
617- this .weight = weight
618- this .age = age
619- }
620- init {
621- this .color = color
622- }
623-
624622```
625623
626624可以发现,多个init语句块有利于进一步对初始化的操作进行职能分离,这在复杂的业务开发中显得特别有用。
@@ -768,31 +766,7 @@ class Person // 从 Any 隐式继承
768766```
769767
770768` Any ` 不是` java.lang.Object ` 。它除了` equals() ` 、` hashCode() ` 和` toString() ` 外没有任何成员。
771- ` Kotlin ` 中所有的类默认都是不可继承的(` final ` ),为什么要这样设计呢?引用` Effective Java ` 书中的第17条:要么为继承而设计,并提供文档说明,
772- 要么就禁止继承。所以我们只能继承那些明确声明` open ` 或者` abstract ` 的类:要声明一个显式的超类型,我们把类型放到类头的冒号之后:
773-
774- ``` kotlin
775- open class Person (num : Int )
776- // 继承
777- class SuperPerson (num : Int ) : Person(num)
778- ```
779-
780- 冒号后面的Person(num)会调用Person类的构造函数,以确保所有的初始化代码(例如给属性赋值)能够被执行。调用父类构造函数是强制性的:如果父类有主构造函数,你必须在子类头中调用它,否则代码将无法通过编译。请记住,即使你没有在父类中显式地添加构造函数,编译器也会在编译代码的时候自动创建一个空构造函数。假如我们不想为Person类添加构造函数,因此编译器在编译代码的时候创建了一个空构造函数。该构造函数通过使用Person()被调用。
781-
782-
783-
784- 如果该类有一个主构造函数,其基类必须用基类型的主构造函数参数就地初始化。
785- 如果类没有主构造函数,那么每个次构造函数必须使用` super ` 关键字初始化其基类型,或委托给另一个构造函数做到这一点。
786- 注意,在这种情况下,不同的次构造函数可以调用基类型的不同的构造函数:
787-
788- ``` kotlin
789- class MyView : View {
790- constructor (ctx: Context ) : super (ctx)
791- constructor (ctx: Context , attrs: AttributeSet ) : super (ctx, attrs)
792- }
793- ```
794-
795- 在Java中,类默认是可以被继承的,除非你主动加final修饰符。而在Kotlin中恰好相反,默认是不可被继承的,除非你主动加可以继承的修饰符,那便是open,如果不加open,那它在转化为Java代码时就是final的:
769+ `在Java中,类默认是可以被继承的,除非你主动加final修饰符。而在Kotlin中恰好相反,默认是不可被继承的,除非你主动加可以继承的修饰符,那便是open,如果不加open,那它在转化为Java代码时就是final的:
796770
797771``` kotlin
798772class Bird {
@@ -825,6 +799,27 @@ public final class Bird {
825799}
826800```
827801
802+ 所以Kotlin` 中所有的类默认都是不可继承的( ` final` ),为什么要这样设计呢?引用 ` Effective Java`书中的第17条:要么为继承而设计,并提供文档说明,
803+ 要么就禁止继承。所以我们只能继承那些明确声明` open ` 或者` abstract ` 的类:要声明一个显式的超类型,我们把类型放到类头的冒号之后:
804+
805+ ``` kotlin
806+ open class Person (num : Int )
807+ // 继承
808+ class SuperPerson (num : Int ) : Person(num)
809+ ```
810+
811+ 冒号后面的Person(num)会调用Person类的构造函数,以确保所有的初始化代码(例如给属性赋值)能够被执行。调用父类构造函数是强制性的:如果父类有主构造函数,你必须在子类头中调用它,否则代码将无法通过编译。请记住,即使你没有在父类中显式地添加构造函数,编译器也会在编译代码的时候自动创建一个空构造函数。假如我们不想为Person类添加构造函数,因此编译器在编译代码的时候创建了一个空构造函数。该构造函数通过使用Person()被调用。
812+
813+ 如果该类有一个主构造函数,其基类必须用基类型的主构造函数参数就地初始化。
814+ 如果类没有主构造函数,那么每个次构造函数必须使用` super ` 关键字初始化其基类型,或委托给另一个构造函数做到这一点。
815+ 注意,在这种情况下,不同的次构造函数可以调用基类型的不同的构造函数:
816+
817+ ``` kotlin
818+ class MyView : View {
819+ constructor (ctx: Context ) : super (ctx)
820+ constructor (ctx: Context , attrs: AttributeSet ) : super (ctx, attrs)
821+ }
822+ ```
828823
829824
830825### Any
@@ -1090,7 +1085,7 @@ fun main(args: Array<String>) {
10901085}
10911086```
10921087
1093- 从Kotlin1.3版本器 ,你可以忽略main函数的参数,写成如下形式:
1088+ 从Kotlin1.3版本起 ,你可以忽略main函数的参数,写成如下形式:
10941089
10951090``` kotlin
10961091fun main () {
@@ -1105,7 +1100,7 @@ fun main() {
11051100### 可变长参数函数:使用` vararg ` 关键字
11061101
11071102``` kotlin
1108- fun vars (vararg v : Int ){
1103+ fun vars (vararg v : Int ){
11091104 for (vt in v){
11101105 print (vt)
11111106 }
0 commit comments