以下內容純粹為本人學習期間總結破喻,如有錯誤之處煩請指正不勝感激??
此次學習分享的內容均是Kotlin
入門基礎語法;協(xié)程,Anko
跛蛋,擴展屬性等等還沒涉及到
繼承
- Java
class A extends B { }
- Kotlin
class A : B() {}
接口
- Java
class A implements B, C {}
- Kotlin
class A : B, C {}
override
在
Java
中是注解庆揪。重寫父類方法,實現(xiàn)接口方法
在Kotlin
中成了類似關鍵字的東西囚枪。重寫和實現(xiàn)自帶了,不再是注解
- Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
- Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
Object 類
-
Java
中Object
是所有類型的頂級父類 -
Kotlin
中并沒有Object
劳淆,取而代之的是Any()
链沼,意義和Java
中的Object
一樣。注意此處指的是大寫O
的Object
沛鸵,非小寫o
的object
結扎關鍵字
-
Java
和Kotlin
都不能繼承自結扎類 -
Java
中用final
修飾的類不可被繼承括勺,并且Java
中的類不聲明為final
的話則默認可被繼承 -
Kotlin
中則和Java
相反,Kotlin
中的類默認是被結扎的曲掰,不可被繼承疾捍,除非使用了open
關鍵字 -
Kotlin
中如果某個類被聲明為abstract
,則不需要使用open
進行修飾了栏妖,默認已經(jīng)帶上
實例化對象
- Java
Person person = new Person(bug, 需求)乱豆;
- Kotlin
var person = Person(bug, 需求)
打印日志
- Java
System.out.print("打印日志");
System.out.println("打印日志");
- Kotlin
print("打印日志")
println("打印日志")
常量與變量
- Java
String name = "Hello Java";
final String name = "Hello 結扎過的 Java";
- Kotlin
var name = "Hello Kotlin"
val name = "Hello 結扎過的 Kotlin"
null聲明
- Java
String otherName;
otherName = null;
- Kotlin
//在類型后面跟英文問號代表此變量可空
var otherName : String?
otherName = null
空判斷
- Java
if (text != null) {
int length = text.length();
}
- Kotlin
text?.let {
val length = text.length
}
// 簡單寫法
val length = text?.length
字符串拼接
- Java
String firstName = "ja";
String lastName = "va";
String message = "名字是: " + firstName + " " + lastName;
- Kotlin
val firstName = "Ko"
val lastName = "tlin"
val message = "名字是: $firstName $lastName"
換行
- Java
String text = "第一行\(zhòng)n" +
"第二行\(zhòng)n" +
"第三行";
- Kotlin
//又叫多行文本字符串
val text = """
|第一行
|第二行
|第三行
""".trimMargin()
//trimMargin()方法是Kotlin自己的,用于替換掉字符串中的指定符號吊趾,點擊查看源碼可知默認值是"|"宛裕,所以我們可以依照自己的需求來進行替換
val text = """
>First Line
|Second Line
>Third Line
""".trimMargin(">")
//這樣就只會替換掉第一行和第三行前面的大于符號
三目運算符
- Java
String text = x > 5 ? "x > 5" : "x <= 5";
- Kotlin
val text = if (x > 5)
"x > 5"
else "x <= 5"
//簡單寫法
var s: String? = null
var text = s ?: "空了" //s為空么?不為空返回自己论泛,為空返回"空了"
操作符
- java
final int andResult = a & b;
final int orResult = a | b;
final int xorResult = a ^ b;
final int rightShift = a >> 2;
final int leftShift = a << 2;
- Kotlin
val andResult = a and b
val orResult = a or b
val xorResult = a xor b
val rightShift = a shr 2
val leftShift = a shl 2
類型判斷和轉換 (聲明式)
- Java
if (object instanceof Car) {
}
Car car = (Car) object;
- Kotlin
if (object is Car) {
}
var car = object as Car
類型判斷和轉換 (隱式)
- Java
if (object instanceof Car) {
Car car = (Car) object;
}
- Kotlin
if (object is Car) {
var car = object // smart casting
}
多重條件
- Java
if (score >= 0 && score <= 300) { }
- Kotlin
if (score in 0..300) { }
更靈活的case語句
- Java
int score = // some score;
String grade;
switch (score) {
case 10:
case 9:
grade = "Excellent";
break;
case 8:
case 7:
case 6:
grade = "Good";
break;
case 5:
case 4:
grade = "OK";
break;
case 3:
case 2:
case 1:
grade = "Fail";
break;
default:
grade = "Fail";
}
- Kotlin
var score = // some score
var grade = when (score) {
9, 10 -> "Excellent"
in 6..8 -> "Good"
4, 5 -> "OK"
in 1..3 -> "Fail"
else -> "Fail"
}
for循環(huán)
- Java
for (int i = 1; i <= 10 ; i++) { }
for (int i = 1; i < 10 ; i++) { }
for (int i = 10; i >= 0 ; i--) { }
for (int i = 1; i <= 10 ; i+=2) { }
for (int i = 10; i >= 0 ; i-=2) { }
for (String item : collection) { }
for (Map.Entry<String, String> entry: map.entrySet()) { }
- Kotlin
for (i in 1..10) { }
for (i in 1 until 10) { }
for (i in 10 downTo 0) { }
for (i in 1..10 step 2) { }
for (i in 10 downTo 1 step 2) { }
for (item in collection) { }
for ((key, value) in map) { }
更方便的集合操作一
- Java
final List<Integer> listOfNumber = Arrays.asList(1, 2, 3, 4);
final Map<Integer, String> keyValue = new HashMap<Integer, String>();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");
// Java 9
final List<Integer> listOfNumber = List.of(1, 2, 3, 4);
final Map<Integer, String> keyValue = Map.of(1, "Java",
2, "Kotlin",
3, "Scala",
4, "Swift");
- Kotlin
val listOfNumber = listOf(1, 2, 3, 4)
val keyValue = mapOf(1 to "Java",
2 to "Kotlin",
3 to "Scala",
4 to "Swift")
更方便的集合操作二
- Java
List<String> list = new ArrayList();
list.add("Java");
list.add("Kotlin");
list.add("Scala");
list.add("Swift");
Map<Integer, String> map = new HashMap();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");
- Kotlin
var list = mutableListOf<String>()
list.add("Java")
list.add("Kotlin")
list.add("Scala")
list.add("Swift")
var map = mutableMapOf<Int, String>()
map.put(1, "Java")
map.put(2, "Kotlin")
map.put(3, "Scala")
map.put(4, "Swift")
遍歷
- Java
// Java 7 和以前
for (Car car : cars) {
System.out.println(car.speed);
}
// Java 8+
cars.forEach(car -> System.out.println(car.speed));
// Java 7 和以前
for (Car car : cars) {
if (car.speed > 100) {
System.out.println(car.speed);
}
}
// Java 8+
cars.stream().filter(car -> car.speed > 100).forEach(car -> System.out.println(car.speed));
- Kotlin
cars.forEach {
println(it.speed)
}
cars.filter { it.speed > 100 }
.forEach { println(it.speed)}
方法定義
- Java
void doSomething() {
}
void doSomething(int... numbers) {
}
- Kotlin
fun doSomething() {
}
fun doSomething(vararg numbers: Int) {
}
帶返回值的方法
- Java
int getScore() {
return score;
}
- Kotlin
fun getScore(): Int {
return score
}
//可直接在方法后返回
fun getScore(): Int = score
無結束符號
- Java
int getScore(int value) {
return 2 * value;
}
- Kotlin
fun getScore(value: Int): Int {
return 2 * value
}
//可直接在方法后返回
fun getScore(value: Int): Int = 2 * value
constructor 構造器
- Java
public class Utils {
private Utils() {
}
public Utils(Int i ,String s){
}
}
- Kotlin
class Utils constructor(i: Int, s: String) {
//這種方式的構造器是顯示構造器揩尸,聲明類的時候定好構造方法,實例化的時候必須按照參數(shù)列表進行實例化
var utils = Utils(1, "")
}
class Utils (i: Int, s: String) {
//上面的方式可省略 constructor 關鍵字
var utils = Utils(1, "")
}
class Utils {
constructor(i: Int, s: String)
//上面同樣可以寫成這種樣子屁奏,構造函數(shù)單獨寫進類里面
var utils = Utils(1, "")
}
class Utils private constructor(i: Int, s: String) {
//如果 constructor 前面有修飾符岩榆,則不能省略
var utils = Utils()
}
class Utils private constructor() {
constructor(i: Int, s: String) : this() {
//這種聲明表示我們有一個私有的構造方法,無參的,也可以有參朗恳,自己定義就好湿颅;然后我們公開了一個有參的構造方法供外部進行實例化
var utils = Utils(1, "")
}
}
class Utils constructor(i: Int = 2, s: String = "") {
//如果構造方法中給定了默認值,那么在實例化對象的時候可以不傳入?yún)?shù)粥诫,不傳的話實例化出來的對象默認參數(shù)就是構造方法中的參數(shù)
var utils = Utils()
var utils = Utils(1)
var utils = Utils("")
var utils = Utils(1, "")
}
class Utils constructor(i: Int, s: String = "") {
//但如果參數(shù)列表中有那種沒有給定值的變量時油航,實例化時必須要將他們都傳入構造方法
var utils = Utils(1)
var utils = Utils(1, "")
}
//引申內容,方法重載怀浆,注意和下面的 Kotlin 擴展函數(shù)區(qū)別開
class MainActivityKotlin {
override fun onCreate(saveInstance: Bundle?) {
super.onCreate(savedInstanceState)
makeToast()
makeToast("test")
makeToast(time = Toast.LENGTH_LONG)
makeToast("test", Toast.LENGTH_LONG)
makeToast(msg = "test", time = Toast.LENGTH_LONG)
}
fun makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, msg, time).show()
}
}
Kotlin 擴展函數(shù)
- Kotlin
//擴展函數(shù)一般用在工具類的封裝上谊囚,可以對現(xiàn)有的函數(shù)在不繼承的情況下進行擴展
//object 聲明下面會講到
//擴展函數(shù)一般寫法是,fun 關鍵字 加上要擴展的類的類名执赡,以及方法名
object Utils {
fun Activity.makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, msg, time).show()
}
}
//調用時如下
//從調用處的包引入`import com.danlu.kotlindemo.Utils.makeToast`可以知道镰踏,擴展函數(shù)實際上是以靜態(tài)被引入的,事實上它是靜態(tài)解析的
//除了擴展函數(shù)沙合,還有擴展屬性
class MainActivityKotlin : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
makeToast()
makeToast("test")
makeToast(time = Toast.LENGTH_LONG)
makeToast("test", Toast.LENGTH_LONG)
makeToast(msg = "test", time = Toast.LENGTH_LONG)
}
}
Get Set 構造器
- Java
public class Developer {
private String name;
private int age;
public Developer(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Developer developer = (Developer) o;
if (age != developer.age) return false;
return name != null ? name.equals(developer.name) : developer.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Developer{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- Kotlin
data class Developer(val name: String, val age: Int)
靜態(tài)
- Java
public class Utils {
private Utils() {
}
public static int getDBVersion() {
return CURRENT_DB_VERSION;
}
}
int db_verison = Utils.getDBVersion();
- Kotlin
Kotlin
中使用object
修飾靜態(tài)類奠伪,被修飾的類,可以使用類名.方法名
的形式調用
object Utils {
fun getDBVersion(): Int {
return CURRENT_DB_VERSION
}
}
var db_verison = Utils.getDBVersion()
Kotlin
中使用companion object
修飾靜態(tài)方法首懈,稱為伴生對象绊率,可以使用類名.方法名
的形式調用
class Utils {
companion object {
fun getDBVersion(): Int {
return CURRENT_DB_VERSION
}
}
}
var db_verison = Utils.getDBVersion()
權限修飾符
Java
- public 對所有類可見
- default 在同一包內可見,不寫默認
default
- protected 對同一包內的類和所有子類可見
- private 在同一類內可見
Kotlin
- public 凡是能夠訪問到這個類的地方, 同時也能訪問這個類的
public
成員究履,不寫默認是public
- internal 在
module
之內, 凡是能夠訪問到這個類的地方, 同時也能訪問到這個類的internal
成員 - protected 與
private
一樣, 另外在子類中也可以訪問 - private 表示只在這個類(以及它的所有成員)之內可以訪問滤否,不會自動生成
getter setter
方法
標簽(@)
- Java
loop:
for (int i = 0; i < 100; i++) {
loop1:
for (int j = 0; j < 100; j++) {
if (i == 3) {
continue loop1;
} else if(i == 5) {
continue loop;
} else {
break loop1;
}
}
}
Java
中的標簽我們用的極少,它主要是用來控制流程語句的執(zhí)行最仑,continue
藐俺,break
。用法是:在語句內部需要continue
泥彤,break
的地方欲芹,在控制關鍵字后跟上你想控制的某個循環(huán)。簡單地說就是吟吝,一個循環(huán)一組標簽耀石,起始和終止位置標簽內容一致。在循環(huán)內部爸黄,任意地方可以控制其他循環(huán)。為了方便跳轉到指定位置-
在循環(huán)開始之前用自定義的名字加上英文冒號作為起始點揭鳞,然后書寫循環(huán)語句
loop:循環(huán)語句體...continue/break loop;
Kotlin
val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
ints.forEach foreach@ {
if (it == 0) return@foreach
print(it)
}
- 由于
Kotlin
中幾乎萬物都是表達式炕贵,所以會有方法后直接跟運算體的寫法。Kotlin
中的標簽和Java
中大同小異野崇,只不過在循環(huán)控制上多了return
称开,用來指定:在指定位置返回,上面的代碼就說明在 it== 0時返回,不打印鳖轰,所以打印結果是 123456 - 另外
Kotlin
中的標簽還可以用在this
關鍵字上清酥。Java
中我們通常有XXXActivity.this
的寫法,用來代指XXXActivity
這個引用蕴侣,Kotlin
中寫法是this@XXXActivity
init代碼塊
class Test public constructor(val i: Int) {
// 只對主構造方法生效
init {
}
constructor(i: Int, s: String) : this(i) {
}
fun xxx() {
}
}
上述代碼中焰轻,定義了
Test
類的兩個構造方法,參數(shù)列表不同昆雀;實例化時可以:val test = Test(1) val test1 = Test(1, "")
而某些操作可能需要在默認/主構造方法中進行初始化辱志,也就是單參數(shù)的構造方法中,所以這時候就有
init
代碼塊狞膘;Kotlin
主構造函數(shù)不能包含任何的代碼揩懒,所以初始化的代碼可以放到init
塊中進行
lateinit 和 by lazy
對象/變量可以通過依賴注入來初始化, 或者在單元測試的
setup
方法中初始化挽封。 這種情況下已球,我們并不能直接在構造方法內提供一個非空構造器,但我們使用時依然想要避免對象/變量的空問題辅愿,所以智亮。。渠缕。
-
lateinit
意思是延遲初始化鸽素,只有當變量/對象被聲明為var
時才可使用 -
by lazy
意思是懶初始化,只有當變量/對象被聲明為val
時才可使用
// by lazy 使用方式后面跟大括號亦鳞,里面進行對象/變量的實例化/賦值
// by lazy 只會在第一次使用 danluUtil / name / id 的時候才會創(chuàng)建對象或者實例初始化變量
// 和 java 中的懶漢式單例一樣馍忽,使用時候判空,不為空直接返回對象燕差,為空的話實例化對象再返回
val danluUtil by lazy {
DanluUtil(i, j)
}
val name by lazy {"名字"}
val id by lazy {1}
// lateinit 使用方式在 var 前面加上 lateinit 即可遭笋,后面跟上變量和變量類型
// lateinit 聲明的變量/對象,不能為空徒探,也不能被立即初始化:比如下面兩種方式都是不允許的:
// lateinit var danluUtil: DanluUtil = DanluUtil(i, j)
// lateinit var danluUtil: DanluUtil?
// 大致來說瓦呼,這段代碼將變量的初始化與定義分離開了
// 使用場景包括但不限于依賴注入框架(例如 Dagger2),那些預先聲明的變量也無法成功初始化测暗。在這種情況下央串,必須使用 lateinit 關鍵字確保變量在稍后將被初始化
lateinit var danluUtil: DanluUtil
// 聲明完畢后在需要用到的地方進行初始化:
danluUtil = DanluUtil(i, j)