1、Inheritance(继承)
使用 @JvmOverloads
可以极大的简化构造函数的模板代码
Java 版本
class CustomView : View {
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attrs: AttributeSet?) :
this(context, attrs, 0)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
//...
}
}
Kotlin 版本
class KotlinView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
因为我们使用了 @JvmOverloads
注解,会生成如下字节码:
public KotlinView(Context context) {
super(context);
}
public KotlinView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public KotlinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
2、Interface(接口)
当不同的接口有相同的签名方法时,在调用时,必须要明确写明是哪个接口。例:
interface A {
fun foo() {
println("A")
}
}
interface B {
fun foo() {
println("B")
}
}
class Item : A, B {
override fun foo() {
println("Item")
}
}
//usage
val item = Item()
item.foo() //prints: Item
因为没有标明具体的父类,所以,这里只调用到了自己的方法,没调用接口的方法。
如果需要接口中的方法被调用,需要使用 super<接口名>.接口方法名
写法
class Item : A, B {
override fun foo() {
val a = super<A>.foo()
val b = super<B>.foo()
print("Item $a $b")
}
}
//usage
val item = Item()
item.foo()
//Prints: A B ItemsAB**
3、Object declaration
Java 版本
//synchronized
public class Singleton {
private static Singleton instance = null;
private Singleton(){
}
private synchronized static void createInstance() {
if (instance == null) {
instance = new Singleton();
}
}
public static Singleton getInstance() {
if (instance == null) createInstance();
return instance;
}
}
在 Kotlin 中,我们使用 object
替代 class
关键字
object SQLiteSingleton {
fun getAllUsers(): List<User> {
//...
}
}
//usage
SQLiteSingleton.getAllUsers()
4、Object expression
Java 匿名类
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
//...
}
@Override
public void onServiceConnected(ComponentName name,
IBinder service)
{
//...
}
}
Kotlin 匿名类
val serviceConnection = object: ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) { }
override fun onServiceConnected(name: ComponentName?,service: IBinder?) { }
}
val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
println("Got a broadcast ${intent.action}")
}
}
val intentFilter = IntentFilter("SomeAction");
registerReceiver(broadcastReceiver, intentFilter)
5、Enum
enum class Color {
RED,
ORANGE,
BLUE,
GRAY,
VIOLET
}
val favouriteColor = Color.BLUE
Java 形式
val selectedColor = Color.valueOf("BLUE")
println(selectedColor == Color.BLUE) // prints: true
Kotlin 形式
val selectedColor = enumValueOf<Color>("BLUE")
println(selectedColor == Color.BLUE) // prints: true
Java 循环
for (color in Color.values()) {
println("name: ${it.name}, ordinal: ${it.ordinal}")
}
Kotlin 循环
for (color in enumValues<Color>()) {
println("name: ${it.name}, ordinal: ${it.ordinal}")
}
// Prints:
name: RED, ordinal: 0
name: ORANGE, ordinal: 1
name: BLUE, ordinal: 2
name: GRAY, ordinal: 3
name: VIOLET, ordinal: 4
6、Infix
data class Point(val x: Int, val y: Int) {
infix fun moveRight(shift: Int) = Point(x + shift, y)
}
val pointA = Point(1,4)
// 不带 . 的调用
val pointB = pointA moveRight 2
或
val pointB = pointA.moveRight(2)
println(pointB) //prints: Point(x=3, y=4)
7、Sealed
sealed class Employee()
class Programmer : Employee()
class Manager : Employee()
object CEO : Employee()
sealed
本身就是 abstract
的,所以这里就把 abstract
省略了。sealed
的修饰符是 private
的。
8、Import aliases
Qualified versus unqualified class name
import com.facebook.ads.InterstitialAd
val fbAd = InterstitialAd(context, "...") // Qualified
val googleAd = com.google.android.gms.ads.InterstitialAd(context) // Unqualified
Use Alias
import com.facebook.ads.InterstitialAd as FbAd
import com.google.android.gms.ads.InterstitialAd as GoogleAd
val fbAd = FbAd(context, "...")
val googleAd = GoogleAd(context)