Kotlin 简明教程
Kotlin - Overview
Kotlin 是一种新的开源编程语言,如 Java、JavaScript 等。它是一种高级强静态类型语言,在同一位置组合了函数和技术部分。目前,Kotlin 目标是 Java 和 JavaScript。它在 JVM 上运行。
Kotlin 受到 Java、Scala、Groovy、Gosu 等其他编程语言的影响。Kotlin 的语法可能与 JAVA 不是完全相似,然而,在内部 Kotlin 依赖于现有的 Java 类库来为程序员产生理想的结果。Kotlin 为世界各地的开发人员提供了互操作性、代码安全性和清晰度。
Advantages and Disadvantages
以下是为您的应用程序开发使用 Kotlin 的一些优势。
Easy Language − Kotlin 是一种函数语言,非常容易学习。语法与 Java 非常相似,因此非常容易记住。Kotlin 更具表现力,这使您的代码更具可读性和可理解性。
Concise − Kotlin 基于 JVM,它是一种函数语言。因此,它减少了其他编程语言中使用的大量样板代码。
Runtime and Performance − 更好的性能和较小的运行时间。
Interoperability − Kotlin 已足够成熟,可以以不太复杂的方式构建一个可互操作的应用程序。
Brand New − Kotlin 是一种全新的语言,它让开发者拥有了全新的开始。它不是 Java 的替代品,尽管它是基于 JVM 开发的。它被接受为 Android 开发的首个官方语言。Kotlin 可以被定义为 - Kotlin = JAVA + 额外更新的新特性。
以下是 Kotlin 的一些劣势。
Namespace declaration − Kotlin 允许开发者在顶层声明函数。然而,无论何时在应用程序的许多地方声明相同的函数,都很难理解正在调用哪个函数。
No Static Declaration − Kotlin 没有像 Java 那样的常规静态处理修饰符,这可能会给传统的 Java 开发者带来一些问题。
Kotlin - Environment Setup
但是,如果你仍然想在本地系统中离线使用 Kotlin,那么你需要执行以下步骤来配置你的本地工作空间。
Step 1 − 安装 Java 8。
Kotlin 运行在 JVM 上,因此,你的本地 Kotlin 开发真的需要使用 JDK 8。请参阅 oracle 的官方网站下载并安装 JDK 8 或更高版本。你可能需要设置 JAVA的环境变量,以便它能够正常工作。要在 Windows 操作系统中验证你的安装,请在命令提示符中输入 “java –version”,作为输出,它将显示你的系统中安装的 java 版本。
Step 2 − 安装 IDE。
网上有许多 IDE 可用。你可以使用你选择的任何 IDE。你可以在下表中找到不同 IDE 的下载链接。
IDE Name |
Installation Link |
NetBeans |
|
Eclipse |
|
Intellij |
链接:https://www.jetbrains.com/idea/download/#section = windows[[role="bare"] [role="bare"]https://www.jetbrains.com/idea/download/#section = windows] |
始终建议使用最新的软件版本,以从中最大限度地发挥功能。
Step 3 − 配置 Eclipse。
打开 Eclipse 并转到 “Eclipse Market Place”。你会找到以下屏幕。
在搜索框中搜索 Kotlin,并在你的本地系统中安装它。这可能需要一些时间,具体取决于互联网速度。一旦成功安装,你可能需要重新启动 Eclipse。
Step 4 − Kotlin 项目。
一旦成功重新启动 Eclipse 并安装了 Kotlin,你就可以立即创建一个 Kotlin 项目。转到 File → New → Others 并从列表中选择 “Kotlin project”。
一旦项目设置完成,你就可以在 “SRC” 文件夹下创建一个 Kotlin 文件。左键单击 “Src” 文件夹并单击 “new”。你会看到一个用于 Kotlin 文件的选项,否则你可能需要从 “others” 中搜索。一旦创建新文件,你的项目目录将如下所示。
你的开发环境现在已经准备就绪。继续在 “Hello.kt” 文件中添加以下代码片段。
fun main(args: Array<String>) {
println("Hello, World!")
}
将它作为 Kotlin 应用程序运行,并在控制台中查看输出,如下面的屏幕截图所示。为了更好的理解和可用性,我们将使用我们的编码地工具。
Hello, World!
Kotlin - Architecture
科特林是一种编程语言,拥有自己的内存分配和向最终用户输出高质量内容的体系结构。以下是科特林编译器在以包括 Java 和 JavaScript 在内的其他各种语言为目标时将以不同方式工作的不同场景。
科特林编译器创建一个字节码,而该字节码可以在 JVM 上运行,这与由 Java .class 文件生成的字节码完全相同。只要两个字节码文件在 JVM 上运行,它们即可互相通信,而这就是如何为 Java 语言在科特林中建立互操作性功能的。
每当科特林以 JavaScript 为目标时,科特林编译器将 .kt 文件转换为 ES5.1,并为 JavaScript 生成兼容的代码。科特林编译器能够通过 LLVM 创建平台基础兼容代码。
Kotlin - Basic Types
在本章中,我们将了解科特林编程语言中可用的基本数据类型。
Numbers
科特林中数字的表示与 Java 非常相似,但是,科特林不允许不同数据类型之间的内部转换。下表列出了不同数字的不同可变长度。
Type |
Size |
Double |
64 |
Float |
32 |
Long |
64 |
Int |
32 |
Short |
16 |
Byte |
8 |
在以下示例中,我们将看到科特林如何使用不同数据类型。请在我们的编码区域中输入以下代码集。
fun main(args: Array<String>) {
val a: Int = 10000
val d: Double = 100.00
val f: Float = 100.00f
val l: Long = 1000000004
val s: Short = 10
val b: Byte = 1
println("Your Int Value is "+a);
println("Your Double Value is "+d);
println("Your Float Value is "+f);
println("Your Long Value is "+l);
println("Your Short Value is "+s);
println("Your Byte Value is "+b);
}
当您在编码区域中运行以上代码段时,它将在网络控制台中生成以下输出。
Your Int Value is 10000
Your Double Value is 100.0
Your Float Value is 100.0
Your Long Value is 1000000004
Your Short Value is 10
Your Byte Value is 1
Characters
科特林使用 char 表示字符。字符应像 ‘c’ 一样用单引号声明。请在我们的编码区域中输入以下代码,并查看科特林如何解释字符变量。字符变量不能像数字变量一样声明。科特林变量可以通过两种方式声明 - 一种使用 “var” ,另一种使用 “val” 。
fun main(args: Array<String>) {
val letter: Char // defining a variable
letter = 'A' // Assigning a value to it
println("$letter")
}
以上代码段将在浏览器输出窗口中产生以下输出。
A
Boolean
布尔值非常简单,就像其他编程语言一样。我们只有两个布尔值 - true 或 false。在以下示例中,我们将看到科特林如何解释布尔值。
fun main(args: Array<String>) {
val letter: Boolean // defining a variable
letter = true // Assinging a value to it
println("Your character value is "+"$letter")
}
以上代码段将在浏览器中产生以下输出。
Your character value is true
Strings
字符串是字符数组。和 Java 一样,它们本质上是不可变的。在我们有两种字符串可供选择 - 一种称为 raw String ,另一种称为 escaped String 。在以下示例中,我们将使用这些字符串。
fun main(args: Array<String>) {
var rawString :String = "I am Raw String!"
val escapedString : String = "I am escaped String!\n"
println("Hello!"+escapedString)
println("Hey!!"+rawString)
}
上面转义字符串的示例允许在第一个打印语句后提供额外的行空间。以下是浏览器中的输出。
Hello!I am escaped String!
Hey!!I am Raw String!
Arrays
阵列是同类数据的集合。科特林与 Java 类似,支持不同数据类型的阵列。在以下示例中,我们将使用不同的阵列。
fun main(args: Array<String>) {
val numbers: IntArray = intArrayOf(1, 2, 3, 4, 5)
println("Hey!! I am array Example"+numbers[2])
}
以上代码段产生以下输出。阵列的索引与其他编程语言类似。在这里,我们正在搜索第二个索引,其值为“3”。
Hey!! I am array Example3
Collections
集合是数据结构中非常重要的部分,它使工程师可以轻松地进行软件开发。科特林有两种类型的集合 - 一种是 immutable collection (表示不可编辑的列表、映射和集合),另一种是 mutable collection (此类型的集合可编辑)。牢记应用程序中使用的集合类型非常重要,因为科特林系统不会对其表示任何特定的差异。
fun main(args: Array<String>) {
val numbers: MutableList<Int> = mutableListOf(1, 2, 3) //mutable List
val readOnlyView: List<Int> = numbers // immutable list
println("my mutable list--"+numbers) // prints "[1, 2, 3]"
numbers.add(4)
println("my mutable list after addition --"+numbers) // prints "[1, 2, 3, 4]"
println(readOnlyView)
readOnlyView.clear() // ⇒ does not compile
// gives error
}
以上代码段将在浏览器中产生以下输出。当我们尝试清除集合的可变列表时,它会给出错误。
main.kt:9:18: error: unresolved reference: clear
readOnlyView.clear() // -> does not compile
^
在集合中,科特林提供了一些有用的方法,例如 first(), last(), filter() 等。所有这些方法都是自描述的并且易于实现。此外,科特林在执行集合时遵循与 Java 相同的结构。您可以自由实现任何集合(例如映射和集合)。
在以下示例中,我们已使用不同的内置方法实现了映射和集合。
fun main(args: Array<String>) {
val items = listOf(1, 2, 3, 4)
println("First Element of our list----"+items.first())
println("Last Element of our list----"+items.last())
println("Even Numbers of our List----"+items.
filter { it % 2 = = 0 }) // returns [2, 4]
val readWriteMap = hashMapOf("foo" to 1, "bar" to 2)
println(readWriteMap["foo"]) // prints "1"
val strings = hashSetOf("a", "b", "c", "c")
println("My Set Values are"+strings)
}
以上代码片段将在浏览器中产生以下输出。
First Element of our list----1
Last Element of our list----4
Even Numbers of our List----[2, 4]
1
My Set Values are[a, b, c]
Ranges
范围是柯林的另一项独特特征。像 Haskell 一样,它提供一个帮助你遍历范围的运算符。在内部,它是使用 rangeTo() 实现的,其运算符形式为 (..) 。
在下面的示例中,我们将看到柯林如何解释这个范围运算符。
fun main(args: Array<String>) {
val i:Int = 2
for (j in 1..4)
print(j) // prints "1234"
if (i in 1..10) { // equivalent of 1 < = i && i < = 10
println("we found your number --"+i)
}
}
以上代码片段将在浏览器中产生以下输出。
1234we found your number --2
Kotlin - Control Flow
在上一章中,我们学习了柯林系统中可用的不同类型的数据类型。本章中,我们将讨论柯林中可用的不同类型的控制流机制。
If - Else
柯林是一种函数式语言,因此像柯林中每个函数式语言 “if” 一样是一种表达式,它不是一个关键字。表达式 “if” 将在需要时返回一个值。像其他编程语言一样, “if-else” 块用作初始条件检查运算符。在下面的例子中,我们将比较两个变量,并相应地提供必需的输出。
fun main(args: Array<String>) {
val a:Int = 5
val b:Int = 2
var max: Int
if (a > b) {
max = a
} else {
max = b
}
print("Maximum of a or b is " +max)
// As expression
// val max = if (a > b) a else b
}
上述代码段在浏览器中生成如下输出。我们的示例还包含另一行代码,它描述了如何使用 “If” 语句作为一个表达式。
Maximum of a or b is 5
Use of When
如果你熟悉其他编程语言,那么你可能听说过 switch 语句这一术语,它基本上是当多个条件可以应用到特定变量上的条件运算符。 “when” 运算符将变量值与分支条件进行匹配。如果它满足分支条件,那么它将在该范围中执行语句。在下面的例子中,我们将更多地了解柯林中的“when”。
fun main(args: Array<String>) {
val x:Int = 5
when (x) {
1 -> print("x = = 1")
2 -> print("x = = 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
}
以上代码片段将在浏览器中产生以下输出。
x is neither 1 nor 2
在上面的示例中,柯林编译器将 x 的值与给定的分支进行匹配。如果它与任何一个分支都不匹配,那么它将执行 else 部分。实际上,when 等价于多个 if 块。柯林为开发人员提供了另一个灵活性,开发人员可以通过在检查中提供“,”,在同一行中提供多个检查。让我们修改上面的示例,如下所示。
fun main(args: Array<String>) {
val x:Int = 5
when (x) {
1,2 -> print(" Value of X either 1,2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
}
在浏览器中运行同样的代码,这将在浏览器中产生以下输出。
x is neither 1 nor 2
For Loop
循环是一种提供遍历任何类型数据结构的灵活性的发明。像其他编程语言一样,柯林还提供了多种循环方法,但是,其中 “For” 是最成功的一个。For 循环的实现和使用与 Java for 循环的概念类似。以下示例展示了我们如何在实际示例中使用它。
fun main(args: Array<String>) {
val items = listOf(1, 2, 3, 4)
for (i in items) println("values of the array"+i)
}
在上面的代码段中,我们声明了一个名为“items”的列表,并使用 for 循环遍历该已定义的列表,并在浏览器中打印其值。以下是输出。
values of the array1
values of the array2
values of the array3
values of the array4
以下是另一个代码示例,在其中我们使用一些库函数使我们的开发工作比以往任何时候都更加容易。
fun main(args: Array<String>) {
val items = listOf(1, 22, 83, 4)
for ((index, value) in items.withIndex()) {
println("the element at $index is $value")
}
}
在编码环境中编译和运行上述代码段后,将在浏览器中生成以下输出。
the element at 0 is 1
the element at 1 is 22
the element at 2 is 83
the element at 3 is 4
While Loop and Do-While Loop
While 和 Do-While 的工作方式与其他编程语言中完全一样。这两个循环之间的唯一区别是,在 Do-while 循环中,将在循环末尾测试条件。以下示例演示了 While loop 的用法。
fun main(args: Array<String>) {
var x:Int = 0
println("Example of While Loop--")
while(x< = 10) {
println(x)
x++
}
}
以上代码片段将在浏览器中产生以下输出。
Example of While Loop--
0
1
2
3
4
5
6
7
8
9
10
Kotlin 还具有另一个称为 Do-While 的循环,其中循环体将执行一次,然后才检查条件。以下示例演示了 Do-while loop 的用法。
fun main(args: Array<String>) {
var x:Int = 0
do {
x = x + 10
println("I am inside Do block---"+x)
} while(x <= 50)
}
上述代码段在浏览器中生成以下输出。在上述代码中,Kotlin 编译器将执行 DO 块,然后执行 while 块中的条件检查。
I am inside Do block---10
I am inside Do block---20
I am inside Do block---30
I am inside Do block---40
I am inside Do block---50
I am inside Do block---60
Use of Return, Break, Continue
如果你熟悉任何编程语言,那么你一定了解有助于我们在应用程序中实现良好的控制流的不同关键字。以下是可用于控制循环或任何其他类型的控制流的不同关键字。
Return − Return 是一個關鍵字,用於將某個值從被調用函數返回給調用函數。在以下示例中,我們將使用 Kotlin 編碼環境實現此情境。
fun main(args: Array<String>) {
var x:Int = 10
println("The value of X is--"+doubleMe(x))
}
fun doubleMe(x:Int):Int {
return 2*x;
}
在上述代码段中,我们调用另一个函数并将输入乘以 2,并将结果值返回给被调用的函数,即我们的主函数。Kotlin 以不同的方式定义函数,我们将在后续章节中研究此函数。现在,我们只要理解上述代码将在浏览器中生成以下输出即可。
The value of X is--20
Continue & Break − Continue 和 break 是逻辑问题中最重要的部分。“break” 关键字在某个条件失败时终止控制器流,“continue” 则执行相反的操作。所有这些操作都以立即可见的模式发生。Kotlin 比其他编程语言更智能,其中开发者可以将多个标签应用为可见性。以下代码片段演示了我们在 Kotlin 中实现此标签的方式。
fun main(args: Array<String>) {
println("Example of Break and Continue")
myLabel@ for(x in 1..10) { // appling the custom label
if(x = = 5) {
println("I am inside if block with value"+x+"\n-- hence it will close the operation")
break@myLabel //specifing the label
} else {
println("I am inside else block with value"+x)
continue@myLabel
}
}
}
以上代码片段将在浏览器中产生以下输出。
Example of Break and Continue
I am inside else block with value1
I am inside else block with value2
I am inside else block with value3
I am inside else block with value4
I am inside if block with value5
-- hence it will close the operation
正如您看到的,此控制器继续循环,直到 x 的值为 5。当 x 的值达到 5 时,它开始执行 if 块,并且一旦到达 break 语句,整个控制流就终止了程序执行。
Kotlin - Class & Object
在本章中,我们将使用 Kotlin 学习面向对象编程 (OOP) 的基础知识。我们将学习类及其对象,以及如何使用该对象。根据 OOP 的定义,类是运行时实体的蓝图,对象是其状态,包括其行为和状态。在 Kotlin 中,类声明由类头和用大括号括起来的类主体组成,类似于 Java。
Class myClass { // class Header
// class Body
}
与 Java 类似,Kotlin 也允许创建类的多个对象,您还可以自由地包含其类成员和函数。我们可以使用将在第 10 章中学习的不同关键字来控制类成员变量的可见性——可见性控制。在以下示例中,我们将创建一个类及其对象,通过该类和对象我们将访问该类的不同数据成员。
class myClass {
// property (data member)
private var name: String = "Tutorials.point"
// member function
fun printMe() {
print("You are at the best Learning website Named-"+name)
}
}
fun main(args: Array<String>) {
val obj = myClass() // create obj object of myClass class
obj.printMe()
}
上述代码段将在浏览器中产生以下输出,其中我们使用其自己的对象调用 myClass 的 printMe()。
You are at the best Learning website Named- Tutorials.point
Nested Class
根据定义,当一个类在另一个类中创建时,它被称为嵌套类。在 Kotlin 中,嵌套类默认是静态的,因此无需创建该类的任何对象即可访问它。在以下示例中,我们将看到 Kotlin 如何解释我们的嵌套类。
fun main(args: Array<String>) {
val demo = Outer.Nested().foo() // calling nested class method
print(demo)
}
class Outer {
class Nested {
fun foo() = "Welcome to The TutorialsPoint.com"
}
}
以上代码段将在浏览器中产生以下输出。
Welcome to The TutorialsPoint.com
Inner Class
当一个嵌套类标记为“内部”时,它将被称为内部类。可以通过外部类的数据成员访问内部类。在以下示例中,我们将访问外部类的数据成员。
fun main(args: Array<String>) {
val demo = Outer().Nested().foo() // calling nested class method
print(demo)
}
class Outer {
private val welcomeMessage: String = "Welcome to the TutorialsPoint.com"
inner class Nested {
fun foo() = welcomeMessage
}
}
上述代码段将在浏览器中产生以下输出,其中我们使用 Kotlin 编译器在编译时提供的默认构造函数调用嵌套类。
Welcome to the TutorialsPoint.com
Anonymous Inner Class
匿名内部类是一个非常好的概念,它让程序员的生活变得非常轻松。每当我们实现接口时,匿名内部块的概念就会进入视野。使用运行时对象引用创建接口对象的概念称为匿名类。在以下示例中,我们将创建一个接口,并使用匿名内部类机制创建该接口的对象。
fun main(args: Array<String>) {
var programmer :Human = object:Human // creating an instance of the interface {
override fun think() { // overriding the think method
print("I am an example of Anonymous Inner Class ")
}
}
programmer.think()
}
interface Human {
fun think()
}
以上代码段将在浏览器中产生以下输出。
I am an example of Anonymous Inner Class
Kotlin - Constructors
在本章中,我们将学习 Kotlin 中的构造函数。Kotlin 有两种类型的构造函数——一种是 primary constructor ,另一种是 secondary constructor 。一个 Kotlin 类可以有一个主构造函数和一个或多个辅助构造函数。Java 构造函数初始化成员变量,但是,在 Kotlin 中,主构造函数初始化类,而辅助构造函数有助于在初始化相同内容时包含一些额外的逻辑。主构造函数可以在类头级别声明,如下例所示。
class Person(val firstName: String, var age: Int) {
// class body
}
在上面的示例中,我们在括号内声明了主构造函数。在两个字段中,名字是只读的,因为它被声明为“val”,而年龄字段可以编辑。在以下示例中,我们将使用主构造函数。
fun main(args: Array<String>) {
val person1 = Person("TutorialsPoint.com", 15)
println("First Name = ${person1.firstName}")
println("Age = ${person1.age}")
}
class Person(val firstName: String, var age: Int) {
}
上述代码段将自动初始化两个变量并在浏览器中提供以下输出。
First Name = TutorialsPoint.com
Age = 15
如前所述,Kotlin 允许为您的类创建一或多个辅助构造函数。这个辅助构造函数是使用“constructor”关键字创建的。只要您想在 Kotlin 中创建多个构造函数或当您想在主构造函数中包含更多逻辑并且您无法这样做时,就需要它,因为主构造函数可能被其他类调用。看一看下面的例子,我们在其中创建了一个辅助构造函数并使用上面的例子来实现它。
fun main(args: Array<String>) {
val HUman = HUman("TutorialsPoint.com", 25)
print("${HUman.message}"+"${HUman.firstName}"+
"Welcome to the example of Secondary constructor, Your Age is-${HUman.age}")
}
class HUman(val firstName: String, var age: Int) {
val message:String = "Hey!!!"
constructor(name : String , age :Int ,message :String):this(name,age) {
}
}
Note - 可以创建任意数量的辅助构造函数,但是,所有这些构造函数都应该直接或间接地调用主构造函数。
以上代码段将在浏览器中产生以下输出。
Hey!!! TutorialsPoint.comWelcome to the example of Secondary constructor, Your Age is- 25
Kotlin - Inheritance
在本章中,我们将学习继承。根据定义,我们都知道继承意味着将母类的一些属性累积到子类中。在 Kotlin 中,基类被命名为“Any”,它是 Kotlin 中声明的“任何”默认类的超类。像所有其他 OOP 一样,Kotlin 也使用一个称为 “:” 的关键字提供此功能。
Kotlin 中的一切默认都是 final 的,因此,我们需要在类声明前使用关键字“open”使其允许继承。看一看下面的继承示例。
import java.util.Arrays
open class ABC {
fun think () {
print("Hey!! i am thiking ")
}
}
class BCD: ABC(){ // inheritence happend using default constructor
}
fun main(args: Array<String>) {
var a = BCD()
a.think()
}
以上代码段将在浏览器中产生以下输出。
Hey!! i am thiking
现在,如果我们想在子类中覆盖 think() 方法怎么办?然后,我们需要考虑以下示例,我们在其中创建两个类并将其中一个函数覆盖到子类中。
import java.util.Arrays
open class ABC {
open fun think () {
print("Hey!! i am thinking ")
}
}
class BCD: ABC() { // inheritance happens using default constructor
override fun think() {
print("I Am from Child")
}
}
fun main(args: Array<String>) {
var a = BCD()
a.think()
}
上述代码段将调用子类继承的方法,它将在浏览器中产生以下输出。像 Java 一样,Kotlin 也不允许多重继承。
I Am from Child
Kotlin - Interface
在本章中,我们将学习 Kotlin 中的接口。在 Kotlin 中,接口与 Java 8 的工作完全类似,这意味着它们可以包含方法实现以及抽象方法声明。接口可以通过一个类来实现,以便使用其定义的功能。我们已经在第 6 章“匿名内部类”部分中引入了一个带有接口的示例。本章将进一步学习它。关键字“interface”用于在 Kotlin 中定义一个接口,如下面的代码片段所示。
interface ExampleInterface {
var myVar: String // abstract property
fun absMethod() // abstract method
fun sayHello() = "Hello there" // method with default implementation
}
在上面的示例中,我们创建了一个名为“ExampleInterface”的接口,其中我们有几个抽象属性和方法。看看名为“sayHello()”的方法,这是一个已实现的方法。
在下面的示例中,我们将在类中实现上面的接口。
interface ExampleInterface {
var myVar: Int // abstract property
fun absMethod():String // abstract method
fun hello() {
println("Hello there, Welcome to TutorialsPoint.Com!")
}
}
class InterfaceImp : ExampleInterface {
override var myVar: Int = 25
override fun absMethod() = "Happy Learning "
}
fun main(args: Array<String>) {
val obj = InterfaceImp()
println("My Variable Value is = ${obj.myVar}")
print("Calling hello(): ")
obj.hello()
print("Message from the Website-- ")
println(obj.absMethod())
}
以上代码段将在浏览器中产生以下输出。
My Variable Value is = 25
Calling hello(): Hello there, Welcome to TutorialsPoint.Com!
Message from the Website-- Happy Learning
如前所述,Kotlin 不支持多重继承,但是通过一次实现两个以上的接口可以实现相同的事情。
在以下示例中,我们将创建两个接口,稍后我们将在类中实现这两个接口。
interface A {
fun printMe() {
println(" method of interface A")
}
}
interface B {
fun printMeToo() {
println("I am another Method from interface B")
}
}
// implements two interfaces A and B
class multipleInterfaceExample: A, B
fun main(args: Array<String>) {
val obj = multipleInterfaceExample()
obj.printMe()
obj.printMeToo()
}
在上面的示例中,我们创建了两个示例接口 A,B,在名为“multipleInterfaceExample”的类中,我们实现了前面声明的两个接口。以上代码段将在浏览器中产生以下输出。
method of interface A
I am another Method from interface B
Kotlin - Visibility Control
在本章中,我们将学习 Kotlin 语言中提供的不同修饰符。 Access modifier 用于限制应用程序中使用的变量、方法和类的用法。与其他 OOP 编程语言一样,此修饰符可应用于多处,例如类头或方法声明中。Kotlin 中提供了四个访问修饰符。
Private
类、方法和包可以用 private 修饰符声明。一旦声明为 private,则它将在其直接作用域内可访问。例如,私有包可以在该特定文件中访问。私有类或接口只能通过其数据成员等访问。
private class privateExample {
private val i = 1
private val doSomething() {
}
}
在上面的示例中,类 “privateExample” 和变量 i 都只能在同一个 Kotlin 文件中访问,因为它们都在声明块中声明为 private。
Protected
Protected 是另一个 Kotlin 访问修饰符,它目前不可用于顶级声明,例如任何包都不能被保护。受保护的类或接口仅对它的子类可见。
class A() {
protected val i = 1
}
class B : A() {
fun getValue() : Int {
return i
}
}
在上面的示例中,变量 “i” 被声明为 protected,因此它仅对它的子类可见。
Kotlin - Extension
在本章中,我们将学习 Kotlin 的另一个新特性,称为“扩展”。使用扩展,即使不继承或修改它们,我们也可以添加或删除一些方法功能。扩展在统计上得到解决。它实际上并没有修改现有类,而是创建了一个可通过点操作调用的可调用函数。
Function Extension
在函数扩展中,Kotlin允许在主类的外部定义一个方法。在以下示例中,我们将了解如何在函数级别实现扩展。
class Alien {
var skills : String = "null"
fun printMySkills() {
print(skills)
}
}
fun main(args: Array<String>) {
var a1 = Alien()
a1.skills = "JAVA"
//a1.printMySkills()
var a2 = Alien()
a2.skills = "SQL"
//a2.printMySkills()
var a3 = Alien()
a3.skills = a1.addMySkills(a2)
a3.printMySkills()
}
fun Alien.addMySkills(a:Alien):String{
var a4 = Alien()
a4.skills = this.skills + " " +a.skills
return a4.skills
}
在以上示例中,“Alien”类内没有名为“addMySkills()”的方法,不过,我们在类的外部的其他位置实现了相同的方法,这就是扩展的妙处。
上面的代码段将在浏览器中生成以下输出。
JAVA SQL
Object Extension
Kotlin 提供了另一种机制来实现 Java 的静态功能。这可以通过使用关键字“伴生对象”来实现。使用这种机制,我们可以在工厂方法中创建类的对象,然后我们只需使用类名的引用即可调用该方法。在以下示例中,我们将创建一个“伴生对象”。
fun main(args: Array<String>) {
println("Heyyy!!!"+A.show())
}
class A {
companion object {
fun show():String {
return("You are learning Kotlin from TutorialsPoint.com")
}
}
}
以上代码段将在浏览器中产生以下输出。
Heyyy!!! You are learning Kotlin from TutorialsPoint.com
以上示例看起来像Java中的静态,但是在实际时间中,我们正在创建对象作为同一类中的成员变量。这就是它也包含在扩展属性下并且还可以称为对象扩展的原因。您基本上是在扩展同一类的对象以使用某些成员函数。
Kotlin - Data Classes
在本章中,我们将更多地了解 Kotlin 编程语言的数据类。每当类被标记为“data”时,都可以将类标记为数据类。这种类型的类可用于保存基本数据。除此之外,它不提供任何其他功能。
所有数据类都需要有一个主构造函数,并且所有主构造函数都应该至少有一个参数。每当类被标记为数据时,我们可以使用数据类的一些内置函数,例如“toString()”、“hashCode()”等。任何数据类都不能具有抽象、开放或内部等修饰符。数据类也可以扩展到其他类。在以下示例中,我们将创建一个数据类。
fun main(args: Array<String>) {
val book: Book = Book("Kotlin", "TutorialPoint.com", 5)
println("Name of the Book is--"+book.name) // "Kotlin"
println("Puclisher Name--"+book.publisher) // "TutorialPoint.com"
println("Review of the book is--"+book.reviewScore) // 5
book.reviewScore = 7
println("Printing all the info all together--"+book.toString())
//using inbuilt function of the data class
println("Example of the hashCode function--"+book.hashCode())
}
data class Book(val name: String, val publisher: String, var reviewScore: Int)
上面的代码段将在浏览器中产生以下输出,我们创建了一个数据类来保存一些数据,并从 main 函数中访问了它所有的数据成员。
Name of the Book is--"Kotlin"
Puclisher Name--"TutorialPoint.com"
Review of the book is--5
Printing all the info all together--(name-Kotlin, publisher-TutorialPoint.com, reviewScore-7)
Example of the hashCode function---1753517245
Kotlin - Sealed Class
在本章中,我们将学习另一种称为“密封”类的类类型。这种类型的类用于表示受限的类层次结构。密封允许开发人员维护预定义类型的类型。为了创建一个密封类,我们需要使用关键字“sealed”作为该类的修饰符。一个密封类可以有自己的子类,但所有这些子类都需要与密封类一起声明在同一个 Kotlin 文件中。在以下示例中,我们将看到如何使用密封类。
sealed class MyExample {
class OP1 : MyExample() // MyExmaple class can be of two types only
class OP2 : MyExample()
}
fun main(args: Array<String>) {
val obj: MyExample = MyExample.OP2()
val output = when (obj) { // defining the object of the class depending on the inuputs
is MyExample.OP1 -> "Option One has been chosen"
is MyExample.OP2 -> "option Two has been chosen"
}
println(output)
}
在上面的示例中,我们有一个名为“MyExample”的密封类,它只能是两种类型之一——一种是“OP1”,另一种是“OP2”。在主类中,我们在类中创建一个对象,并在运行时分配它的类型。现在,由于这个“MyExample”类是密封的,我们可以将“when ” 子句应用于运行时以实现最终输出。
在密封类中,我们不需要使用任何不必要的“else”语句来使代码复杂化。以上代码段将在浏览器中产生以下输出。
option Two has been chosen
Kotlin - Generics
与 Java 一样,Kotlin 提供了称为泛型的变量类型的更高阶。在本章中,我们将学习 Kotlin 如何实现泛型,以及作为开发人员,我们如何使用泛型库中提供的那些功能。在实现方面,泛型与 Java 非常相似,但 Kotlin 开发人员引入了两个新关键字 “out” 和 “in” ,以使 Kotlin 代码更具可读性和更容易被开发者理解。
在 Kotlin 中,类和类型是完全不同的概念。根据示例,List 在 Kotlin 中是一个类,而 List<String> 在 Kotlin 中是一个类型。下面的示例描述了泛型如何在 Kotlin 中实现。
fun main(args: Array<String>) {
val integer: Int = 1
val number: Number = integer
print(number)
}
在上面的代码中,我们声明了一个“整数”,然后将该变量赋值给一个数字变量。这是可能的,因为“Int”是 Number 类的子类,因此类型转换在运行时自动发生,并产生“1”的输出。
让我们进一步了解 Kotlin 中的泛型。最好在不确定我们在应用程序中要使用的数据类型时使用泛型数据类型。通常,Kotlin 中的泛型由 <T> 定义,其中“T”代表模板,它可以由 Kotlin 编译器动态确定。在以下示例中,我们将看到如何在 Kotlin 编程语言中使用泛型数据类型。
fun main(args: Array<String>) {
var objet = genericsExample<String>("JAVA")
var objet1 = genericsExample<Int>(10)
}
class genericsExample<T>(input:T) {
init {
println("I am getting called with the value "+input)
}
}
在上面的代码段中,我们创建了一个具有泛型返回类型的类,表示为 <T> 。看看 main 方法,我们在运行时动态定义它的值,同时创建该类的对象时提供值类型。这就是 Kotlin 编译器如何解释泛型的。一旦我们在编码基础中运行此代码,我们将在浏览器中获得以下输出。
I am getting called with the value JAVA
I am getting called with the value 10
当我们要将泛型类型分配给它的任何超类型时,我们需要使用“out”关键字,当我们要将泛型类型分配给它的任何子类型时,我们需要使用“in”关键字。在以下示例中,我们将使用“out”关键字。同样,你也可以尝试使用“in”关键字。
fun main(args: Array<String>) {
var objet1 = genericsExample<Int>(10)
var object2 = genericsExample<Double>(10.00)
println(objet1)
println(object2)
}
class genericsExample<out T>(input:T) {
init {
println("I am getting called with the value "+input)
}
}
上面的代码将在浏览器中产生以下输出。
I am getting called with the value 10
I am getting called with the value 10.0
genericsExample@28d93b30
genericsExample@1b6d3586
Kotlin - Delegation
Kotlin 通过引入新关键字 “by” 来支持 “delegation” 设计模式。使用此关键字或委派方法,Kotlin 允许派生类通过特定对象访问接口的所有已实现的公共方法。以下示例演示了如何在 Kotlin 中实现此目的。
interface Base {
fun printMe() //abstract method
}
class BaseImpl(val x: Int) : Base {
override fun printMe() { println(x) } //implementation of the method
}
class Derived(b: Base) : Base by b // delegating the public method on the object b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).printMe() // prints 10 :: accessing the printMe() method
}
在这个示例中,我们有一个名为“Base”的接口,其抽象方法名为“printme()”。在 BaseImpl 类中,我们正在实现这个“printme()”,然后在另一个类中,我们使用“by”关键字使用这个实现。
以上代码段将在浏览器中产生以下输出。
10
Property Delegation
在上一节中,我们已经学习了如何使用“by”关键字委派设计模式。在本节中,我们将学习如何使用 Kotlin 库中提到的某些标准方法委派属性。
委派是指将责任传递给另一个类或方法。当某个属性已经在某些地方声明时,我们应重复使用同一代码来初始化它们。在下面的示例中,我们将使用 Kotlin 提供的一些标准委派方法和在示例中实现委派时的一些标准库函数。
Using Lazy()
Lazy 是一个 lambda 函数,它将一个属性作为输入,并返回一个 Lazy<T> 实例,其中 <T> 是它使用的属性的基本类型。我们看一下以下内容来理解它是如何工作的。
val myVar: String by lazy {
"Hello"
}
fun main(args: Array<String>) {
println(myVar +" My dear friend")
}
在上面的代码片段中,我们向 Lazy 函数传递一个变量“myVar”,它反过来将值分配给其对象,并将其返回给主函数。以下是浏览器的输出。
Hello My dear friend
Delegetion.Observable()
Observable() 采用两个参数来初始化对象,并将同一对象返回给被调用函数。在下面的示例中,我们将看到如何使用 Observable() 方法来实现委派。
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("Welcome to Tutorialspoint.com") {
prop, old, new ->
println("$old -> $new")
}
}
fun main(args: Array<String>) {
val user = User()
user.name = "first"
user.name = "second"
}
以上代码段将在浏览器中产生以下输出。
first -> second
通常,语法就是“by”关键字之后的表达式被委派。变量 p 的 get() 和 set() 方法将被委派到其在 Delegate 类中定义的 getValue() 和 setValue() 方法。
class Example {
var p: String by Delegate()
}
对于上面的代码片段,以下是我们为在变量 p 中分配值而需要生成的委派类。
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name} in $thisRef.'")
}
}
读取时,将调用 getValue() 方法;设置变量时,将调用 setValue() 方法。
Kotlin - Functions
Kotlin 是一个静态类型语言,因此函数在其中扮演着重要角色。我们非常熟悉函数,因为我们整个示例中都在使用函数。函数用关键字“fun”声明。像任何其他 OOP 一样,它也需要一个返回类型和一个可选参数列表。
在下面的示例中,我们定义了一个名为 MyFunction 的函数,并且从主函数中调用此函数并传递一些参数。
fun main(args: Array<String>) {
println(MyFunction("tutorialsPoint.com"))
}
fun MyFunction(x: String): String {
var c:String = "Hey!! Welcome To ---"
return (c+x)
}
以上代码段将在浏览器中产生以下输出。
Hey!! Welcome To ---tutorialsPoint.com
函数应如下声明:
fun <nameOfFunction>(<argument>:<argumentType>):<ReturnType>
以下是 Kotlin 中的一些不同类型的函数。
Lambda Function
Lambda 是一个高级函数,它在声明函数并定义同一函数时极大地减少了样板代码。Kotlin 允许你定义自己的 lambda。在 Kotlin 中,你可以声明自己的 lambda 并将该 lambda 传递给函数。
请看以下示例。
fun main(args: Array<String>) {
val mylambda :(String)->Unit = {s:String->print(s)}
val v:String = "TutorialsPoint.com"
mylambda(v)
}
在上面的代码中,我们已经创建了自己的 lambda,名为“mylambda”,并且已经向此 lambda 传递了一个变量,该变量的类型为 String,并且包含一个值“TutorialsPoint.com”。
以上代码段将在浏览器中产生以下输出。
TutorialsPoint.com
Inline Function
上面的示例显示了我们可以在 Kotlin 应用程序中使用的 lambda 表达式的基础知识。现在,我们可以将 lambda 传递到其他函数以获取我们的输出,这使得调用函数成为内联函数。
请看以下示例。
fun main(args: Array<String>) {
val mylambda:(String)->Unit = {s:String->print(s)}
val v:String = "TutorialsPoint.com"
myFun(v,mylambda) //passing lambda as a parameter of another function
}
fun myFun(a :String, action: (String)->Unit) { //passing lambda
print("Heyyy!!!")
action(a)// call to lambda function
}
上面的代码片段将在浏览器中生成以下输出。使用内联函数,我们已经将一个 lambda 作为参数传递。可以使用“inline”关键字将任何其他函数变成内联函数。
Heyyy!!!TutorialsPoint.com
Kotlin - Destructuring Declarations
Kotlin 包含了许多其他编程语言的功能。它允许你同时声明多个变量。此技术称为解构声明。
以下是解构声明的基本语法。
val (name, age) = person
在以上语法中,我们创建了一个对象并通过一个简单的语句将它们全部定义在一起。之后,我们可以如下使用它们。
println(name)
println(age)
现在,让我们看看如何在我们的实际应用程序中使用它们。考虑以下示例,其中我们创建一个包含一些属性的学生类,稍后我们将使用它们来打印对象值。
fun main(args: Array<String>) {
val s = Student("TutorialsPoint.com","Kotlin")
val (name,subject) = s
println("You are learning "+subject+" from "+name)
}
data class Student( val a :String,val b: String ){
var name:String = a
var subject:String = b
}
以上代码段将在浏览器中产生以下输出。
You are learning Kotlin from TutorialsPoint.com
Kotlin - Exception Handling
异常处理是编程语言非常重要的一部分。此技术限制了我们的应用程序在运行时生成错误输出。在本章中,我们将学习如何在 Kotlin 中处理运行时异常。Kotlin 中的异常与 Java 中的异常非常相似。所有异常都是“Throwable”类的后代。以下示例展示了如何在 Kotlin 中使用异常处理技术。
fun main(args: Array<String>) {
try {
val myVar:Int = 12;
val v:String = "Tutorialspoint.com";
v.toInt();
} catch(e:Exception) {
e.printStackTrace();
} finally {
println("Exception Handeling in Kotlin");
}
}
在上面的代码片段中,我们声明了一个字符串,然后将其绑定到整数中,这实际上是一个运行时异常。因此,我们将在浏览器中获得以下输出。
val myVar:Int = 12;
Exception Handeling in Kotlin
Note - 与 Java 一样,Kotlin 也在执行 catch 块后执行 finally 块。