Kotlin學(xué)習(xí)筆記——概覽滋觉、類和對象

更多文章可以訪問我的博客Aengus | Blog

概覽OverView

  • Kotlin的變量或方法聲明和Java相比是“反”的签夭,也就是類型聲明在后,變量或方法名在前椎侠;
  • Kotlin更嚴格第租,這點體現(xiàn)在方法聲明時就確定變量是否可變,類默認不可繼承我纪;
  • Kotlin更安全慎宾,變量聲明的類都是非空的,如果允許為空浅悉,則需要在類后面加?趟据;
  • Kotlin用println()函數(shù)進行打印,并且每行結(jié)束不用加;术健;
  • Kotlin注釋格式與Java相同汹碱;
  • Kotlin支持字符串模板表達式,使用"${expression}"的格式可以對expression進行運算并將其轉(zhuǎn)為字符串荞估;

變量與函數(shù)

Kotlin變量聲明格式如下:

val/var a: Type = someThing

其中val代表不可變咳促,對應(yīng)Java中的final Typevar代表可變變量泼舱,就等同于Java中普通的變量等缀。Type是變量類型,不可空娇昙,如果允許為空尺迂,則用Type?表示。在聲明時便要求聲明變量為valvar冒掌,是Kotlin安全性上的體現(xiàn)噪裕,一般情況下,不可變對象都是線程安全的股毫。

Kotlin一般函數(shù)聲明如下:

fun funcationName(arg: Type): ReturnType {
    // 函數(shù)體
}

可以看到參數(shù)的聲明也是后置類型膳音,ReturnType是函數(shù)的返回類型,也可以不寫返回類型代表無返回值铃诬。Kotlin函數(shù)還有很多用法祭陷,我們將在后面再提到。

在變量或函數(shù)聲明最開始都可以加private等關(guān)鍵字進行修飾趣席。

循環(huán)兵志、List和Map

Kotlin只有for循環(huán)和Java稍有不同,for循環(huán)基本結(jié)構(gòu)為:

for (item: Type in collection) { /* ... */ } // 可以省略類型

若使用數(shù)字迭代宣肚,則常用以下兩種方式:

// 區(qū)間想罕,左閉右閉。下面i = 1,2,3
for (i in 1..3) { /* ... */ }
// until函數(shù)霉涨,左閉右開按价,符合常用習(xí)慣惭适。下面i = 1,2
for (i in 1 until 3) { /* ... */ }
// 可以用 step 和 downTo 控制步長與順序。下面i = 10,8,6,4,2
for (i in 10 downTo 2 step 2) { /* ... */ }

Kotlin使用listOf()生成List楼镐,使用MapOf()生成Map癞志,用法如下:

val list = listOf<String>("a", "b", "c")
print(list[1]) // b
val map = mapOf<String, Int>("key1" to 1, "key2" to 2)
print(map["key1"]) // 1

之后會對集合進行更詳細說明。

一切皆對象

Kotlin相對于Java面向?qū)ο蟮某潭雀呖虿T贙otlin中今阳,Java的boolean,int,char,double等數(shù)據(jù)類型的首字母全部變成大寫,即Boolean,Int,Char等茅信,這意味著這些數(shù)據(jù)類型都是對象,可以使用下面這種方法進行操作:

1.toChar()
true.and(false)
1.2.compareTo(1)

類Class

在Java中墓臭,所有對象都繼承自Object蘸鲸,而在Kotlin中,所有對象均繼承自Any(如果可能是null窿锉,則繼承Any?)酌摇。Any類中有三個方法,分別為hashCode()嗡载,equals()toString()窑多。類聲明與創(chuàng)建方法如下:

class Name {
  // 類主體
}
// 如果類中沒有body體,可以用這種方式
class Empty
// 創(chuàng)建類洼滚,Kotlin中沒有 new 關(guān)鍵字
val person: Person = Person()
// Kotlin擁有類型推導(dǎo)機制埂息,可以省略變量類型聲明
val person = Person()

構(gòu)造函數(shù)Constructor

每個類都可以有一個主構(gòu)造函數(shù)和次構(gòu)造函數(shù)。

主構(gòu)造函數(shù)

主構(gòu)造函數(shù)如下所示:

class Person constructor(firstName: String) { /* ... */ }
// 構(gòu)造函數(shù)無注解時也可以省略 constructor 關(guān)鍵字
class Person(firstName: String) { /* ... */ }
// 若有注解遥巴,則 constructor 關(guān)鍵字不能省略
class Person public @Inject constructor(firstName: String) { /* ... */ }

// 推薦使用
class Person(val firstName: String) { /* ... */ }
// 或者
class Person(private val firstName: String) { /* ... */ }

主構(gòu)造函數(shù)沒有函數(shù)體千康,如果想進行初始化工作(就像Java中的構(gòu)造函數(shù)一樣),可以放在init塊中铲掐,init塊中的函數(shù)會在創(chuàng)建對象時被調(diào)用:

class Person(firstName: String) {
    init {
        println("構(gòu)造函數(shù)")
    }
}

Kotlin的主構(gòu)造函數(shù)有點像是語法糖拾弃,當你調(diào)用構(gòu)造函數(shù)時,Kotlin編譯器會自動將參數(shù)賦值給主構(gòu)造函數(shù)中的聲明的參數(shù)摆霉,這個過程類似于Java中的:

class Person {
   private String name;
  
    public Person(String name) {
        this.name = name;
    }
}
Person person = new Person("Bob");

所以豪椿,Kotlin主構(gòu)造函數(shù)中的參數(shù)可以在類body中任意的地方使用。Kotlin中類携栋,字段和函數(shù)默認修飾符都是public搭盾,protectedprivate關(guān)鍵字作用和Java中保持一致,但是使用internal表示同一module下可見刻两。

如果沒有指定主構(gòu)造函數(shù)增蹭,則編譯器會為其自動生成一個無參的主構(gòu)造函數(shù),這點和Java是一致的磅摹。

次構(gòu)造函數(shù)

次構(gòu)造函數(shù)是在類body中使用constructor函數(shù)進行表示:

class Person {
    constructor(name: String) { /* ... */ }
}

一個類可以有多個次構(gòu)造函數(shù)滋迈,但只能有一個主構(gòu)造函數(shù)霎奢。如果一個類既有主構(gòu)造函數(shù)又有次構(gòu)造函數(shù),那么每個次構(gòu)造函數(shù)必須直接或間接調(diào)用主構(gòu)造函數(shù)饼灿,使用this關(guān)鍵字:

class Person(val name: String) {
      constructor(name: String, age: Int) : this(name) { /* ... */ }
      constructor(name: String, age: Int, sex: String) : this(name, age) { /* ... */ }
}

主構(gòu)造函數(shù)調(diào)用在此構(gòu)造函數(shù)之前幕侠。注意,只有主構(gòu)造函數(shù)中的參數(shù)可以在類body中的任何地方調(diào)用碍彭,此構(gòu)造函數(shù)的參數(shù)只能在構(gòu)造函數(shù)中使用晤硕。下面是一個較為完整的例子:

class Person(val name: String) {
    init {
        println("name: ${this.name}")
    }
    constructor(name: String, age: Int) : this(name) {
        println("name: $name, age: $age")
    }
    constructor(name: String, age: Int, sex: String) : this(name, age) {
        println("name: $name, age: $age, sex: $sex")
    }
}

fun main() {
  val person = Person("張三")
}
// 輸出:
// name: 張三
// name: 張三, age: 18
// name: 張三, age: 18, sex: 男

Kotlin構(gòu)造函數(shù)參數(shù)支持默認值,如下:

class Person(val name: String = "李四") {
    init {
        println("name: ${this.name}")
    }
    constructor(name: String = "王五", age: Int = 20) : this(name) {
        println("name: $name, age: $age")
    }
    constructor(name: String = "趙六", age: Int = 21, sex: String = "男") : this(name, age) {
        println("name: $name, age: $age, sex: $sex")
    }
}
fun main() {
    val person = Person()
    val person1 = Person(name="甲")
    val person2 = Person(name="乙", age=10)
    val person3 = Person(age=30)
    val person4 = Person(sex="女")
}
// 第一行代碼輸出:
// name: 李四
// 第二行代碼輸出:
// name: 甲
// 第三行代碼輸出:
// name: 乙
// name: 乙, age: 10
// 第四行代碼輸出:
// name: 王五
// name: 王五, age: 30
// 第五行代碼輸出:
// name: 趙六
// name: 趙六, age: 21
// name: 趙六, age: 21, sex: 女

可以看到Kotlin會優(yōu)先使用參數(shù)較少的構(gòu)造方法庇忌,當傳入的參數(shù)不在此構(gòu)造方法時舞箍,Kotlin才會選擇參數(shù)更多的構(gòu)造方法。注意次構(gòu)造函數(shù)中參數(shù)不允許使用val/var修飾皆疹。

繼承Inheritance

上面已經(jīng)說到疏橄,所有的類都直接或間接繼承自Any類。在Kotlin中略就,所有的類默認都是final的捎迫,因為類默認是不可繼承的,如果允許其被其他類繼承表牢,則需要使用open關(guān)鍵字進行修飾

open class Person { /* ... */ }

父類指定了主或次構(gòu)造函數(shù)時:如果子類有主構(gòu)造函數(shù)窄绒,則父類必須被在繼承時立即初始化

open class Father(val lastName: String) {
    init {
        println("父親姓 ${lastName}")
    }
}

class Son(val lastNameSon: String) : Father(lastNameSon) {
    init {
        println("兒子姓 $lastNameSon")
    }
}

父類指定了主或次構(gòu)造函數(shù)時:如果子類沒有主構(gòu)造函數(shù),那么它的每個次構(gòu)造函數(shù)都必須使用super初始化父類崔兴,或者委派給另外一個有此功能的此構(gòu)造函數(shù):

open class Father(val lastName: String)

class Son : Father {
    constructor(familyName: String) : super(familyName) {
        println("這里用的是父類的字段lastName=$lastName")
    }
    // 委派給子類的第一個次構(gòu)造函數(shù)
    constructor(familyName: String, age: Int) : this(familyName) {
        println("通過兒子的姓我們知道父親姓 $lastName彰导,兒子 $age 歲了")
    }
}

fun main() {
    val son = Son("王")
    val son2 = Son("王", 20)
}
// 第一行代碼輸出:
// 這里用的是父類的字段lastName=王
// 第二行代碼輸出:
// 這里用的是父類的字段lastName=王
// 通過兒子的姓我們知道父親姓 王,兒子 20 歲了

父類沒有指定主或次構(gòu)造函數(shù)時:如果子類沒有指定主構(gòu)造函數(shù)和次構(gòu)造函數(shù)恼布,那么在繼承時使用父類默認的構(gòu)造函數(shù)螺戳;否則在主構(gòu)造函數(shù)處繼承父類構(gòu)造函數(shù)或者次構(gòu)造函數(shù)處使用super實例化父類:

open class Father

class Son : Father()
class Son2 : Father {
    constructor() : super() { /* ... */ }
}

Kotlin與Java一樣,僅僅支持單繼承折汞,但是可以實現(xiàn)多個接口倔幼。

重寫override

在Java中重寫父類方法使用的是@Override注解,而在Kotlin中則使用override關(guān)鍵字爽待,除此以外函數(shù)默認也是final的损同,如果需要被在子類中重寫同樣需要使用open關(guān)鍵字進行修飾:

open class Father {
    open fun eat() { /* ... */ }
    fun sleep() { /* ... */ }
}
class Son : Father() {
    override fun eat() { /* .... */ }
}

使用final關(guān)鍵字可以使方法不再次被子類重寫(只被自己重寫):

class Son : Father() {
    final override fun eat() { /* .... */ }
}

Kotlin也支持屬性重寫,用法和函數(shù)重寫類似:

open class Father() {
    open val age: Int = 40
}
class Son1(override val age: Int = 22) : Father() // age不可更改
class Son2 : Father() {
    override var age = 20;  // age此時可以更改
}

抽象類Abstract Class

Kotlin中的抽象類與Java類似鸟款,使用abstract關(guān)鍵字進行修飾膏燃,需要注意的是當繼承抽象類時,需要對父類(抽象類)進行實例化:

abstract class Father
class Son : Father()

抽象類默認也是open的何什。

接口Interface

Kotlin使用interface聲明接口组哩,接口中的方法默認為open,且支持默認方法實現(xiàn);接口中也可以有屬性:

interface Worker {
    val count: Int  // 抽象的屬性伶贰,不允許賦值
    fun run() {
       println("Worker中的方法")
   }
}

注意蛛砰,實現(xiàn)類中對接口中的屬性進行重寫,不可以將var屬性變?yōu)?code>val屬性黍衙,但可以將val變?yōu)?code>var泥畅。

當子類同時實現(xiàn)或繼承接口與父類時,重寫規(guī)則如下:

open class Machine {
    open fun run() {
        println("Machine中的方法")
    }
}
class Computer : Machine(), Worker {
    val app = "QQ"
    override fun run() {
        println("Computer中的方法")
    }
    fun runAll() {
        run()
        // 通過這種方式調(diào)用父類或接口的方法
        super<Machine>.run()
        super<Worker>.run()
    }
}
fun main() {
    val com = Computer()
    com.runAll()
}
// 輸出
// Computer中的方法
// Machine中的方法
// Worker中的方法

內(nèi)部類Inner Class

嵌套類就是在類中的類:

class Computer {
    val app = "QQ"
    class Desktop {
        fun print() {
          println("嵌套類中的方法")
        }
    }
}

嵌套類無法訪問外部類的方法或?qū)傩岳欧鞘褂?code>inner關(guān)鍵字修飾嵌套類時位仁,嵌套類就變成了內(nèi)部類,此時就可以訪問到外部類的屬性或方法了方椎,這是因為此時內(nèi)部類含有一個外部類的引用(編譯器自動生成的):

open class Machine {
    open fun playOuter() {
        println("父類方法")
    }
}
class Computer : Machine() {
    val app = "QQ"
    override fun playOuter() {
        println("外部類的方法")
    }
    inner class Desktop {
        fun print() {
            println(app)
        }
        fun play() {
            playOuter()  // 調(diào)用外部類方法
            super@Computer.playOuter() // 調(diào)用外部類的父類的方法
        }
    }
}
fun main() {
    val desktop = Computer().Desktop()
    desktop.print()
    desktop.play()
}
// 輸出:
// QQ
// 外部類的方法
// 父類方法

數(shù)據(jù)類Data Class

在Java中寫JavaBean時聂抢,我們常常需要對其重寫equals(),hashCode(),toString()等方法以便于使用,但這些都是一些重復(fù)的工作棠众,我們也可以借助Lombok中的@Data注解幫我們完成這些工作涛浙,而在Kotlin中,這些工作都可以借助關(guān)鍵字data幫我們實現(xiàn)摄欲。數(shù)據(jù)類的聲明如下:

data class User(val name: String, val age: Int)

另外,數(shù)據(jù)類還給我們提供了函數(shù)copy()幫我們實現(xiàn)數(shù)據(jù)類的復(fù)制疮薇,copy()函數(shù)會針對每個數(shù)據(jù)類生成其對應(yīng)的構(gòu)造方法胸墙,以上面的數(shù)據(jù)類為例,它生成的copy()方法與調(diào)用方式如下:

copy(val name: String, val age: Int)
// 如何使用
val oldUser: User = User("李四", 20)
val newUser: User = oldUser.copy(name="王五")

數(shù)據(jù)類還提供了componentN()函數(shù)返回數(shù)據(jù)類的第N個屬性按咒,以上面的數(shù)據(jù)類為例迟隅,componentN()函數(shù)使用如下:

val user = User("張三", 20)
val name1 = user.component1() // name1 = "張三"
val age1 = user.component2()    // age1 = 20
// 或者(這里的component1(),component2()被自動調(diào)用)
val (name2, age2) = user        // (name2 = "張三", age2 = 20)
// 還可以這么用
val collection = listOf(User("a", 1), User("b", 2), User("3", 3))
for ((name, age) in collection) {
    println("name is $name")
    println("age is $age")
}

數(shù)據(jù)類也可以有類body,我們同樣可以使用自己的方式重寫toString()等方法励七。如果想讓數(shù)據(jù)類擁有無參的構(gòu)造方法智袭,可以給所有參數(shù)指定默認值。如果不想讓編譯器自動將參數(shù)添加到構(gòu)造方法中掠抬,可以將其放在body中:

data class User(val name: String) {
    var age: Int = 18
}

數(shù)據(jù)類目前有以下幾種限制:

  • 主構(gòu)造函數(shù)中至少有一個參數(shù)吼野;

  • 主構(gòu)造函數(shù)中的參數(shù)必須使用val/var修飾;

  • 數(shù)據(jù)類的父類中的final方法不會被重寫两波;

  • 數(shù)據(jù)類不能被abstract,open,sealedinner修飾瞳步;

  • 若父類有open componentN()并且返回兼容的類型,則會被重寫腰奋;若返回不兼容類型单起,則報錯;

密封類Sealed Class

密封類只能被和它同文件的類可見劣坊,對其他文件的類都不可見(但是它的子類可以被其他文件中的類可見)嘀倒。密封類使用sealed關(guān)鍵字修飾:

sealed class Example

密封類是抽象的,而且不可以被實例化,但是可以擁有抽象屬性测蘑。密封類不允許有非private的構(gòu)造方法灌危。

下面的是常用用途:

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
data class Other(val number: Double) : Expr()
// when相當于Java中的switch,但是有更強大的功能如類型轉(zhuǎn)換帮寻,我們將在函數(shù)一節(jié)中說明
fun eval(expr: Expr): Double {
    return when(expr) {
        is Const -> expr.number
        is Sum -> eval(expr.e1) + eval(expr.e2)
        else -> Double.NaN
    }
}

單例類Object Class

在Java中使用單例類是常用的操作乍狐,在這里我們就不給出Java中單例的實現(xiàn)(可以看這篇)。Kotlin中原生支持了單例類的實現(xiàn):

object Singleton {
    fun doSomeThing() { /* ... */ }
}

這種方式聲明的對象是線程安全的固逗,且在第一次訪問時才會被實例化浅蚪,由JVM保證單例。

調(diào)用其方法可以通過類似Java中的靜態(tài)訪問的方式進行:

Singleton.doSomeThing()

單例類也可以繼承其他父類烫罩。單例類可以作為嵌套類在其他類中惜傲,但是不可以在內(nèi)部類中(即不能在inner class):

class Test {
    object Singleton1         // 可以
    inner class Inner {
        object Singleton2 // 不可以
    }
    class Inner2 {
        object Singleton3 // 可以
    }
}

object關(guān)鍵字還有一個作用是作為匿名內(nèi)部類的生成,用法如下:

interface Teacher {
    fun speak()
}

fun giveAClass(t: Teacher) {
    t.speak()
}

fun main() {
    giveAClass(object : Teacher {
        override fun speak() {
            println("臨時老師開始說話")
        }
    })
    // 還可以這么用
    val point = object {
        var x: Int = 100
        var y: Int = 100
    }
    println(point.x)
}

這種通過匿名內(nèi)部類間接實現(xiàn)傳輸函數(shù)的方法在Java中比較常見贝攒,但是Kotlin中還有剛好的方法盗誊,我們將在函數(shù)一節(jié)中繼續(xù)說明。

除此之外隘弊,object還可以作為伴生類的關(guān)鍵字哈踱。

伴生類Companion Class

伴生類的聲明方法如下:

class MyClass {
    companion object Factory {
        val type = "A"
        fun create(): MyClass {
            return MyClass()
        }
    }
}

伴生類可以讓我們用類似Java中靜態(tài)方法調(diào)用的形式掉用某些方法,上面的例子中我們就可以這樣調(diào)用:

val type = MyClass.type
val instance = MyClass.create()
// 或者
val type = MyClass.Factory.type
val instance = MyClass.Factory.create()

伴生類的類名聲明時可以去掉梨熙,這時候Kotlin會自動用Companion作為伴生類的名稱开镣。注意,一個類中只能有一個伴生類咽扇。伴生類同樣可以繼承邪财。

內(nèi)聯(lián)類Inline Class

內(nèi)聯(lián)類目前還在測試中,可能之后會有變化质欲。內(nèi)聯(lián)類表示如下:

inline class Wrapper(val value: Type)

在業(yè)務(wù)中树埠,有時候因為業(yè)務(wù)邏輯需要對某些“東西”進行抽象,而單獨創(chuàng)建對象表示這種“東西”在運行時可能又比較重嘶伟,加大了系統(tǒng)負擔怎憋,內(nèi)聯(lián)類便是用來解決這種問題的,內(nèi)聯(lián)類可以看作一種包裝(Wrapper)九昧,它是對需要包裝的東西的抽象盛霎,在編譯時,Kotlin會為其生成一個包裝器耽装,在運行時愤炸,它要么用這個包裝器代表,要么用它主構(gòu)造函數(shù)中的參數(shù)類型代表掉奄,因此內(nèi)聯(lián)類有且只能有一個主構(gòu)造函數(shù)屬性规个,這個屬性將可能在運行時代替這個內(nèi)聯(lián)類凤薛。有個簡單的例子:

inline class Password(val vaule: String)

這樣便為密碼字符串生成了一個內(nèi)聯(lián)類,既可以方便開發(fā)诞仓,又不用增加系統(tǒng)創(chuàng)建對象的開銷缤苫。關(guān)于“代表”也有個例子,比如Kotlin中的Int墅拭,它既可以用Java中的原始類型int表示活玲,也可以用Integer表示。

內(nèi)聯(lián)類可以繼承其他類谍婉,但是不能被其他類所繼承舒憾,內(nèi)聯(lián)類中可以定義函數(shù)或者其他屬性,但是這些調(diào)用在運行時都將變成靜態(tài)調(diào)用穗熬。

委派Delegation

Kotlin原生支持委派模式镀迂,所謂委派模式,是指將一個對象的工作委派給另一個對象唤蔗,在Kotlin中探遵,委派有類委派與屬性委派湖苞,通過by關(guān)鍵字實現(xiàn)囱晴,通過委派,我們可以將父類的初始化工作交給子類接受的參數(shù):

interface Base {
    val value: Int
    fun printValue()
    fun print()
}
class BaseImpl : Base {
    override val value = 10
    override fun printValue() {
        println("BaseImpl value=${this.value}")
    }
    override fun print() {
        println("BaseImpl print")
    }
}
class Delegation(val base: Base) : Base by base {
    override val value = 20
    override fun print() {
        println("Delegation print")
    }
}
fun main() {
    val baseImpl = BaseImpl()
    val delegation = Delegation(baseImpl)
    delegation.printValue()
    delegation.print()
}
// 輸出:
// BaseImpl value=10
// Delegation print

可以看到使用委派對象后噪径,調(diào)用方法時會優(yōu)先調(diào)用重寫的方法棍掐,但是委派對象只能訪問自己的接口成員(雖然在Delegation中重寫了接口成員规哪,但是委派對象在調(diào)用printValue()時只能訪問自己的接口成員,并不能訪問Delegation中的接口成員)塌衰。

Kotlin提供了函數(shù)lazy()實現(xiàn)了屬性委托,通過by lazy({...})的方式為屬性提供委托并實現(xiàn)了懶加載:

val lazyValue: String by lazy {
    println("進行某些操作")
    "Hello"
}

這里lazy使用了lambda表達式蝠嘉,如果你還不清楚lambda表達式最疆,這里你可以簡單的理解為當代碼運行到這里時,會自動執(zhí)行塊中的代碼蚤告,并將最后一行的值作為塊的返回值努酸。通過lazy函數(shù)進行委托,只有在第一次訪問lazyValue時才會對其進行初始化并記住其值杜恰,之后的訪問將會直接返回這個值获诈。

lazy()函數(shù)默認是線程安全的,如果需要多個線程同時訪問可以傳參LazyThreadSafetyMode.PUBLICATION心褐;如果不需要線程同步可以傳參LazyThreadSafetyMode.NONE舔涎。

還有一個常用的委派方法是使用Map進行傳參,這個方法常常用于解析JSON逗爹,用法如下:

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int by map
}
val user = User(mapOf(
    "name" to "張三",
    "age" to 20
))
println(user.name) // 張三
println(user.age)  // 20
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亡嫌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挟冠,老刑警劉巖于购,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異知染,居然都是意外死亡肋僧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門控淡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嫌吠,“玉大人,你說我怎么就攤上這事逸寓【诱祝” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵竹伸,是天一觀的道長泥栖。 經(jīng)常有香客問我,道長勋篓,這世上最難降的妖魔是什么吧享? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮譬嚣,結(jié)果婚禮上钢颂,老公的妹妹穿的比我還像新娘。我一直安慰自己拜银,他們只是感情好殊鞭,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尼桶,像睡著了一般操灿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泵督,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天趾盐,我揣著相機與錄音,去河邊找鬼小腊。 笑死救鲤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的秩冈。 我是一名探鬼主播本缠,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼入问!你這毒婦竟也來了搓茬?” 一聲冷哼從身側(cè)響起犹赖,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卷仑,沒想到半個月后峻村,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡锡凝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年粘昨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窜锯。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡张肾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锚扎,到底是詐尸還是另有隱情吞瞪,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布驾孔,位于F島的核電站芍秆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏翠勉。R本人自食惡果不足惜妖啥,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望对碌。 院中可真熱鬧荆虱,春花似錦、人聲如沸朽们。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骑脱。三九已至菜枷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惜姐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工椿息, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歹袁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓寝优,卻偏偏與公主長得像条舔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乏矾,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348