kotlin
kotlin变量声明
val 与var
val 定义不可更改的属性 类似于Java的final修饰过的字段
var 定义可变的的属性
完整的定义:
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
var vertexCount: Int
set(value) {
vertexCount = value
}
get() {
return vertexCount
}
val 与var
var name: String ="hello";
var age: Int =19;
var firstName:String?=null; // 赋值为null 主动设置
if --else 与when的使用
val answerString: String = if (count == 42) {
"I have the answer."
} else if (count > 35) {
"The answer is close."
} else {
"The answer eludes me."
}
when的使用类似于Java的switch的使用(无三目运算)
val answerString = when {
count == 42 -> "I have the answer."
count > 35 -> "The answer is close."
else -> "The answer eludes me."
}
方法的定义
方法 用fun修饰
fun xxxxxx(xxx:参数类型,xxx:参数类型):类型(返回类型)
// 不带参数的
fun getUserName(): String {
var tip = when {
age == 19 -> "已成年"
age > 19 -> "已成年"
age < 19 -> "未成年"
else -> "未成年"
}
return tip
}
// 带参数的
fun getUserName(childage:Int,name:String): String {
var tip = when {
childage == 19 -> "已成年"
childage > 19 -> "已成年"
childage < 19 -> "未成年"
else -> "未成年"
}
return tip
}
匿名函数
val stringLengthFunc: (String) -> Int = { input ->
input.length
}
val stringLength: Int = stringLengthFunc("Android")
入参是string类型,出参是int类型,注意该方法使用var修饰的不是fun修饰的
相当于定义了一个变量该变量的值是输入值的input指入参,相当于入参的引用
高阶函数
相当于方法中,再调方法和Java的类似
类的创建
####1.无参构造
class Car() {
private var wheels = wheel
}
####2.有参数的构造,构造方法如有修饰必须使用constructor修饰
class Car(var wheel: List<Wheel>) {
private var wheels = wheel
}
####3.有参构造 切方法重载,重载方法必须继承this
class Car(var wheel: List<Wheel>) {
private var wheels = wheel
constructor(wheel: List<Wheel>, name: String, firstName: String, age: Int) : this(wheel) {
}
}
4.主次构建均存在且多个参数
class Car(var wheel: List<Wheel>) {
private var wheels = wheel
constructor(wheel: List<Wheel>, name: String, firstName: String, age: Int) : this(wheel) {
}
constructor(wheel: List<Wheel>, name: String, firstName: String, age: Int,names:String) : this(wheel) {
}
}
5.init方法要比constructor要早,init类似于static,但是static是在类加载是调用,init是在类初始化的时候。
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor")
}
}
####6.类的继承
kotlin中所有类的父类是any,默认类是不能被继承的,需要被继承需要open关键字
open class Car(var wheel: List<Wheel>) {
}
class CarSon(wheel: List<Wheel>) : Car(wheel) {
}
7.子类没有主构造方法,但是有次构造方法,次构造方法必须使用super关键字
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
8.子类方法的覆盖,必须在父类中open修饰,且被override修饰的方法,被继承,都会是可以被重写的,如果不想被重写,需要使用final 修饰
open class Car(var wheel: List<Wheel>) {
open fun getName(): String {
return ""
}
}
class CarSon(wheel: List<Wheel>) : Car(wheel) {
override fun getName(): String {
return super.getName()
}
}
例如:继承CarSon后的子类是无法调用getName
open class CarSon(wheel: List<Wheel>) : Car(wheel) {
final override fun getName(): String {
return super.getName()
}
}
9.属性的重写
class Car(var wheel: List<Wheel>) {
open fun getName(): String {
return ""
}
open var tts: String = "hello"
open val vertexCount: Int = 0
}
// 重写后的
open class CarSon(wheel: List<Wheel>) : Car(wheel) {
final override fun getName(): String {
return super.getName()
}
override var tts: String="ssdsdsd"
override val vertexCount: Int=1
}
10.子类的初始化与父类的初始化,与Java的一致,先进行父类的,之后进行子类的,在init的方法中使用时要注意使用子类的顺序。
父类的构造方法-init–字段赋值之后是子类的和Java的基本一致。
open class Base(val name: String) {
init { println("Initializing Base") }
open val size: Int =
name.length.also { println("Initializing size in Base: $it") }
}
class Derived(
name: String,
val lastName: String
) : Base(name.capitalize().also { println("Argument for Base: $it") }) {
init { println("Initializing Derived") }
override val size: Int =
(super.size + lastName.length).also { println("Initializing size in Derived: $it") }
}
fun main() {
println("Constructing Derived(\"hello\", \"world\")")
val d = Derived("hello", "world")
}
结果:
ArgConstructing Derived("hello", "world")
Argument for Base: Hello
Initializing Base
Initializing size in Base: 5
Initializing Derived
Initializing size in Derived: 10
11.内部类调用外部类的
文档使用是:super@Outer:,但是实际使用的是直接调用的,应该是文档版本和我的安装的kotlin的文档不一致的结果。
open class Car(var wheel: List<Wheel>) {
open fun getName(): String {
return ""
}
fun getage(): Int {
return 1;
}
open var tts: String = "hello"
open val vertexCount: Int = 0
}
open class CarSon(wheel: List<Wheel>) : Car(wheel) {
final override fun getName(): String {
return super.getName()
}
override var tts: String = super.getName()
override val vertexCount: Int = 1
// 内部类
inner class CarBody {
fun getSonAge(): Int {
return getage()
}
}
}
12.继承类或者实现接口,出现相同方法时,的规则,先看看Java的:
public class Car {
public String getName(){
return "";
}
}
public interface CarInterface {
String getName();
}
public class Son extends Car implements CarInterface{
@Override
public String getName() {
return super.getName();
}
}
java 中已有getName方法了实现接口就不会再让重写getName方法了
open class Car(var wheel: List<Wheel>) {
open fun getName(): String {
return ""
}
fun getage(): Int {
return 1;
}
open var tts: String = "hello"
open val vertexCount: Int = 0
}
interface CarInterface {
fun getName(): String
}
open class CarSon(wheel: List<Wheel>) : Car(wheel),CarInterface{
override var tts: String = super.getName()
override val vertexCount: Int = 1
// 只能重写父类的,接口的无法实现,这和Java的是一样的
override fun getName(): String {
return super.getName()
}
}
还有一种是:不带返回参数的
open class Rectangle {
open fun draw() { /* ... */ }
}
interface Polygon {
fun draw() { /* ... */ } // interface members are 'open' by default
}
class Square() : Rectangle(), Polygon {
// The compiler requires draw() to be overridden:
override fun draw() {
// 明确你要回调的是哪一个父类的方法
super<Rectangle>.draw() // call to Rectangle.draw()
super<Polygon>.draw() // call to Polygon.draw()
}
}
13.抽象类
抽象类和抽象方法和Java的相似,重写的方法也可以做抽象方法基本和Java的一直。
open class Car(var wheel: List<Wheel>) {
open fun getName(): String {
return ""
}
fun getage(): Int {
return 1;
}
open var tts: String = "hello"
open val vertexCount: Int = 0
}
open abstract class CarSon(wheel: List<Wheel>) : Car(wheel),CarInterface{
override var tts: String = super.getName()
override val vertexCount: Int = 1
abstract override fun getName(): String
}
class CarSonSon(wheel: List<Wheel>) : CarSon(wheel) {
override fun getName(): String {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
接口
接口的使用和Java的使用基本一样
特殊的有一点是 data修饰的类,类似于Java的javabean,只实现接口
同时实现多个接口出现同名的接口,无返回参数的接口,可直接成组重写
interface A {
fun foo() { print("A") }
fun bar()
}
interface B {
fun foo() { print("B") }
fun bar() { print("bar") }
}
class C : A {
override fun bar() { print("bar") }
}
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}
override fun bar() {
super<B>.bar()
}
}
可见性修饰符
###修饰符
private:声明该文件的内部可见
public :任何地方可见
peotected:被保护的
intener:内部模块可见的
默认为public
修饰属性,方法,的可见性
修饰类和接口的可见性
对于在类内声明的成员:
private 表示仅在此类内(包括其所有成员)可见;
protected-也与private+在子类中可见;
internal— 该模块内部的任何看到声明类的客户端都会看到其internal成员;
public—任何看到声明类的客户都会看到其public成员。
请注意,在Kotlin中,外部类看不到其内部类的私有成员。
如果您覆盖protected成员并且未明确指定可见性,则覆盖成员也将具有protected可见性。
open class Outer {
private val a = 1
protected open val b = 2
internal val c = 3
val d = 4 // public by default
protected class Nested {
public val e: Int = 5
}
}
class Subclass : Outer() {
// a is not visible
// b, c and d are visible
// Nested and e are visible
override val b = 5 // 'b' is protected
}
class Unrelated(o: Outer) {
// o.a, o.b are not visible
// o.c and o.d are visible (same module)
// Outer.Nested is not visible, and Nested::e is not visible either
}
注:internal修饰的跨model,比如一个lib中的方法或者类被internal修饰,依赖后不可见该方法,或者该类。
泛型
class Box<T>(t: T) {
var value = t;
}
val box: Box<Int> = Box(1);
kotlin的泛型感觉和Java的差不多