kotlin继承了java的全部财产后,语法更加简洁,也更加高级,语言更加安全。学习该语言需要有一定的编程基础。(本人课上学的c语言,自己学过java,只学了一点点,不知道算不算是有编程基础哈,先学再说)
三种方法:
1.下载 intellij IDEA(麻烦)
2.在线编程(外国网站,打不开)
3.Android Studio
不可变变量:val(value)
可变变量:var(variable)
kotlin 拥有出色的类型推导机制,可以不声明类型
当然也可以自己声明,这时kotlin不会运行类型推导机制
如: val a = 10
val a:Int = 10
Kotlin完全抛弃了Java中的基本数据类型,全部使用了对象数据类型。在Java中int是 整型变量的关键字,而在Kotlin中Int变成了一个类,它拥有自己的方法和继承结构。
优先使用val,后考虑var
良好的编程习惯:函数名要有一定的意义
课本中例子:
fun largerNumber(num1: Int ,num2: Int) = max (num1,num2)
见简书:https://www.jianshu.com/p/277ada6d3c3c
下面是if条件语句在kotlin的简化过程
可见kotlin 有Java的额外功能返回值,并且语法糖的作用不小
总结:when语句可以代替多个if,有点像switch,并且它还可以进行类型匹配,需要注意的是要以else结尾
备注:半年前学java 的时候就学过了面向对象的编程,到现在对面向对象几个字还是迷迷糊糊,就知道面向对象可以创建类,其他真的就不知道什么了。
在网上找了一个比较能让自己理解的例子区分面向对象和面向过程,如下:
有一天你想吃鱼香肉丝了,怎么办呢?你有两个选择
1、自己买材料,肉,鱼香肉丝调料,蒜苔,胡萝卜等等然后切菜切肉,开炒,盛到盘子里。
2、去饭店,张开嘴:老板!来一份鱼香肉丝!
看出来区别了吗?这就是1是面向过程,2是面向对象。
面向对象有什么优势呢?首先你不需要知道鱼香肉丝是怎么做的,降低了耦合性。如果你突然不想吃鱼香肉丝了,想吃洛阳白菜,对于1你可能不太容易了,还需要重新买菜,买调料什么的。对于2,太容易了,大喊:老板!那个鱼香肉丝换成洛阳白菜吧,提高了可维护性。总的来说就是降低耦合,提高维护性!
面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。
面向对象是模型化的,你只需抽象出一个类,这是一个封闭的盒子,在这里你拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了,不必去一步一步的实现,至于这个功能是如何实现的,管我们什么事?我们会用就可以了。
面向对象的底层其实还是面向过程,把面向过程抽象成类,然后封装,方便我们我们使用的就是面向对象了。
面向过程:
优点:性能比面向对象好,因为类调用时需要实例化,开销比较大,比较消耗资源。
缺点:不易维护、不易复用、不易扩展.
面向对象
优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护 .
缺点:性能比面向过程差
作者:猪_队友
链接:https://www.jianshu.com/p/7a5b0043b035
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。
上面是官方的语言,这边举例用通俗得语言解释一下类。
如:我们人类是一个类,那么“人”这个类就是抽象的,而真实存在的应该是某个人(具体指明某个人,这个便是是实例化的时候需要做的,实例化后就是对象了)当然这个对象就具有人类所具有的年龄、外貌、能力等属性。
代码如下
package com.example.helloworld
class Person { //创建人 这个类
var name = " " //“人”类的属性
var age = 0 //“人”类的属性
fun eat (){ //“人”类的属性
println(name + "is eating. He is "+ age + "years old.")
}
}
fun main() {
val myfriend = Person() // 这里就是实例化操作
myfriend.age = 19 //以下是对对象进行赋值
myfriend.name = "lihua"
myfriend.eat()
}
以上如果有理解错误或者解释有误,希望大佬指出,感谢!!!
继承:通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。我们称已存在的用来派生新类的类为基类,又称为父类。由已存在的类派生出的新类称为派生类,又称为子类。
简单来说就是子类继承父类的特性,扩展父类的功能。
代码如下:
这里要注意的是:
构造函数(主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值):
主构造函数(没有函数体)
如果需要编写一些逻辑需要用到 init
例如:
class Student(val sno: String,val grade : Int ) : Person(){
init {
println("suo is " + sno)
println("grade is " +grade)
}
}
根据继承的特性规定,子类的构造函数必须调用父类的构造函数
我们需要在子类的主调函数上加上父类主调函数的参数,最后传入父类
例如
class Student(val sno: String,val grade : Int,name : String,age : Int ) : Person(name,age){
init {
println("suo is " + sno)
println("suo is " +grade)
}
}
open class Person(val name :String,val age : Int){
fun eat (){
println(name + "is eating. He is "+ age + "years old.")
}
}
需要注意 子类中定义的name 和 age 没有 val/var 这是避免与父类中的字段造成冲突
次构造函数通过constructor关键字来定义,都必须调用主构造函数(包括间接调用)
代码如下:
箭头表示:
第二个次构造函数调用第一个次构造函数(间接调用)
第一个次构造函数调用主构造函数
因此有三种方式对Student类进行实例化,如下:
val student1 = Student()
val student2 = Student("jack",19)
val student3 = Student("a123",5,"jack",19)
kotlin中允许只有次构造函数,无主构造函数
此时次构造函数直接调用父类的构造函数 关键字 super,并且子类:后少去(),如下:
class Student : Person{
constructor(name : String,age: Int):super(name,age){
}
}
接口有点类似类,但是又有差别,类的抽象是一般化的,而接口就是特殊化
下面直接给出例子:
interface Study {
fun readBooks()
fun doHomework()
}
class Student(name: String,age: Int) : Person(name,age),Study{
override fun readBooks() {
println(name + "is reading book")
}
override fun doHomework() {
println(name + "is doing homework")
}
}
多态(面向接口编程) 如下:
fun main() {
val student = Student("jack",19)
doStudy(student)
}
fun doStudy(study: Study){
study.readBooks()
study.readBooks()
}
这里的Study是个类型(个人理解为能做学习这件事的类型)
所以Student这个类就是能做学习这个事的
所以就是 实例化一个 student 将这个实例传进doStudy()中
kotlin中允许接口中定义的函数进行默认实现。
可见修饰符
小节总结:这节让我重新学习了面向对象编程,之前Java的面向对象编程没有学的很扎实,基本也忘记关了,这节重新算是重新认识了一下。不过感觉学完还是没有很深的认识,大概只是了解了名词和代码实现。学习的过程也花了挺长的时间,大概一节都花了一个下午。。。
List Set Map 集合
List如下:
val list1 = listOf<String>("apple","banana","orange","pear","grape")
for(fruit1 in list1)
println(fruit1)
val list2 = mutableListOf<String>("apple","banana","orange","pear","grape")
list2.add("watermelon")
for(fruit2 in list2 )
println(fruit2)
详细请看:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/array-list-of.html
Set集合 和List 集合相似,set无法保证有序
Map集合如下:
/* val map = HashMap()
map["apple"] = 1
map["banana"] = 2
map["orange"] = 3
map["peat"] = 4
map["grape"] = 5 */
val map = mapOf("apple" to 1,"banana" to 2,"orange" to 3)
for ((fruit,number) in map){ //这里fruit和number的用法注意一下
println("fruit is "+ fruit +",number is " + number)
举例:
这里用map函数映射,然后一个元素进去lambda 出来一个新的元素 最后map合并成一个新的集合
map:
filter:需要注意的是,在filter与其他函数共同使用时,先用filter那样可以提高效率
val list = listOf<String>("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val newlist = list.filter { it.length <= 5 }
.map{it.toUpperCase()}
for (fruit in newlist) {
println(fruit)
}
any:任何一个满足条件
all:所有都满足条件
如下:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val any = list.any{it.length <= 5}
val all = list.all { it.length <= 5 }
println("any is "+any +",all is "+all)
/*
java 版本创建并执行一个子线程
new Thread(new Runnable(){
@Override
public void run(){
System.out.println("Thread is running");
}
}).start()
kotlin 未简化版
Thread (Object : Runnable {
override fun run(){
println("Thread is running")
}
}).strat()
*/
Thread(Runnable {
println("Thread is running")
}).start()
这一小节看的有点迷糊,但是我觉得这些东西应该多接触了就不会,所以在这边直接给出kotlin调用java方法时使用API的语法
fun main() {
doStudy(null)
}
fun doStudy(study: Study?){
if(study != null) { //这里需要对study进行判断 否则会出现 readBoooks() 和 doHomework()
study.readBooks()
study.readBooks()
}
}
fun main() {
doStudy(null)
}
fun doStudy(study: Study?){
study?.readBooks()
study?.readBooks()
}
学习一个 ?: 常用的方法: 表示左边不空则返回左边,否则返回右边的表达式结果
val c = a ?: b
如下:
var content : String? = "hello"
fun main() {
if (content != null){
printupperCase()
}
}
fun printupperCase(){
val upperCase = content!!.toUpperCase()
println(upperCase)
}
fun doStudy(study: Study?) {
study?.let { stu ->
stu.readBooks()
stu.doHomework()
}
}
结合lambda表达式的参数列表中只有一个参数时,可以不用声明参数名化简
fun doStudy(study: Study?) {
study?.let {
it.readBooks()
it.doHomework()
}
}
而且 let 可以处理全局变量,而if不行!!
${ } : 当表达式中只有一个变量的时候,还可以省去大括号。
fun main() {
val brand = "samsung"
val price = 1299.99
println("Cellphone(brand=$brand,price=$price)")
fun printParams(num: Int = 100, str: String) {
println("num is $num , str is $str")
}
fun main() {
printParams(str = "world")
}
这种方式会大程度的替代次构造函数的作用!!
章节总结:这一章节大概花了十个小时的时间,不能说学得很好,也没有很差,面对对象那块确实刚刚学起来有点困难(学java学过,但是没有怎么学)。
以下是一些个人在学习过程中的经验或者说犯的错误