kotlin中文文檔:http://www.kotlindoc.cn/ClassesAndObjects/Classes-and-Inheritance.html
1. 聲明類的構造方法
例如繼承FragmentPagerAdapter時聲明一個構造方法——
class ViewPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) { init { //初始化 } }
當聲明多個構造方法時,如
public class LoadMoreRecyclerView extends RecyclerView { public LoadMoreRecyclerView(Context context) { super(context); } public LoadMoreRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public LoadMoreRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } }
寫作kotlin時,將主構造函數寫在類名后(函數類不使用初始化時可將大括號去掉):
class LoadMoreRecyclerView(context: Context?) : RecyclerView(context) { constructor(context: Context, attrs: AttributeSet):this(context){ } constructor(context: Context, attrs: AttributeSet, defStyle: Int):this(context, attrs) }
如果是一個實體類,需要實現自定義的構造方法:
constructor(id: Long, price: Double, url: String): this() { this.id = id this.price = price this.url = url }
2. 靜態方法
定義靜態方法時用companion object{}包裹在方法外層
3. 定義一個常量不為空時,使用!!和?.的區別:
①!!
a!!.foo()
//相當於java:
if(a!=null){ a.foo(); }else{ throw new KotlinNullPointException(); }
②?.
a?.foo()
//相當於java:
if(a!=null){ a.foo(); }
4. 繼承(extend)和實現(implements)
1.繼承:
java——
public class MainActivity extends BaseActivity{}
kotlin——
class MainActivity : BaseActivity(){}
2.實現:
java——
public class HomeBase implements Parcelable { }
kotlin——
class HomeBase() : Parcelable{}
注意:HomeBase后面跟的小括號即表示一個無參數的構造函數,參見上面說的的《聲明構造方法》
3.同時繼承且實現,逗號隔開就行了:
java——
public class MainActivity extends BaseActivity implements MainContract.View {}
kotlin——
class MainActivity : BaseActivity(), MainContract.View {}
5. 靜態內部類
kotlin默認的內部類是靜態內部類,不能持有外部類的狀態(屬性、方法等)
給內部類加上inner關鍵詞之后,就會變成非靜態內部類
class HomeAdapter{ private inner class SpanSizeLookup : GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { return list[position].spanCount } } }
在非靜態的方法中調用時,需要加上open,即
open inner class SpanSizeLookup : GridLayoutManager.SpanSizeLookup() {
}
6. return的使用
當直接返回到方法外時
fun method{ if (isInEditMode) lit@{ return@lit } }
7. 特殊語法
url == null ? "" : url 可寫作 url ?: ""
holder instanceof HeadHolder 可寫作 holder is HeadHolder
在new一個變量並調用其實現方法時(類似注冊監聽)
MarqueeLayoutAdapter<HomeBase> topAdapter = new MarqueeLayoutAdapter<HomeBase>(headlineList) { @Override protected void initView(View view, int position, HomeBase item) { ((TextView) view).setText(item.getName()); } };
可寫作
val topAdapter = object : MarqueeLayoutAdapter<HomeBase>(headlineList) { override fun initView(view: View, position: Int, item: HomeBase) { (view as TextView).text = item.name } }
8. 修飾符(public,private,protected,internal )
kotlin中同樣有修飾符,與java同樣的public,private,protected,kotlin中默認為public,所以可以省略不寫,還有一個java中沒有的interval修飾符
internal 修飾類的方法,表示這個類方法只適合當前module使用,如果其他module使用的話,會找不到這個internal方法或者報錯
比如在moduleA中創建方法methodA B:
class Activity_A() { fun methodA(){ Log.i("debug=","methodA") } internal fun methodB(){ Log.i("debug=","methodB") } }
然后在moduleB中調用:
void callMethod(){ new Activity_A().methodA(); //正常。
new Activity_A().methodB();//報錯,usage of kotlin internal declaration from different module
}
9. BaseFragment<T>的使用
一般都會有一個fragment的基類,如:
abstract class BaseFragment<T : BasePresenter> : Fragment(){ ... }
當在java中的使用如下時:
private ArrayList<BaseFragment> fragments;
在kotlin中的用法照理(對,照我的理)來說是這樣:
val tabs = ArrayList<BaseFragment>()
但是會報錯
One type argument expected for class BaseFragment<T : BasePresenter> : Fragment
提示需要匹配基類的參數類型,即val tabs = ArrayList<BaseFragment<SomePresenterType>>()
val tabs = ArrayList<BaseFragment<BasePresenter>>()
而BasePresenter如果還有繼承,如
interface BasePresenter<T : BaseView> {}
那么就得再加上basePresenter的參數類型:
val tabs = ArrayList<BaseFragment<BasePresenter<BaseView>>>()
10. 取消findViewById
在kotlin中已經不再使用findViewById了,而是直接使用控件的id名:
java中:
mTextView = view.findViewById(R.id.textl_view);
mTextView.setText("Shirley");
kotlin:
textl_view.text = "Shirley"
11. switch & when
這里就直接上代碼吧
java:
switch (currentState) { case NORMAL_STATE: if (mNormalView == null) { return; } mNormalView.setVisibility(View.INVISIBLE); break;
case ERROR_STATE: mErrorView.setVisibility(View.GONE); default: break; }
kotlin:
when (currentState) { NORMAL_STATE -> { if (mNormalView == null) { return } mNormalView.visibility = View.INVISIBLE } ERROR_STATE -> mErrorView.visibility = View.GONE else -> { } }
12. xx.class的表達
java:
Intent intent = new Intent(this, AboutActivity.class); startActivity(intent);
kotlin:
val intent = Intent(this, AboutActivity::class.java) startActivity(intent)
13.獲取實體類的get/set方法
kotlin的bean類不用寫get/set方法,那么當要調用該方法的時候怎么使用呢
假設實體類為User
class User { var code: Int = 0 var desc: String? = null var tid: String? = null var data: DataBean? = null }
當要獲取 getData() 的時候,直接取 userBean.data ,注意當獲取data后的數據,比如 getData().getName() 時,要做data的非空判斷:userBean.data?.name
而當要 setData() 時,寫作 userBean.data = xx; 即可
14.文件讀取
在kotlin中使用輸入輸出流讀寫文件時,如果照Java寫法
while ((len = inStream.read(buf)) != -1) { fos.write(buf, 0, len); }
則會報錯Assignments are not expressions,and only expressions are allowed in this context
kotlin應寫作
do { len = inStream.read(buf) if (len != -1) { fos.write(buf, 0, len) } } while (true)
15.Array與List互轉
Java:
list --->array
List<String> l = new ArrayList<>(); String[] s = l.toArray(new String[0]);
array ---> list
String[] arr = new String[3]; List<String> list = Arrays.asList(arr);
kotlin:
list --->array
val list = ArrayList<String>()
val arr = a.toTypedArray()
array ---> list
val l = arrayOfNulls<String>(1)//String[] s = new String[1] val list = Arrays.asList<String>(*arr)
需要注意的是分割字符串的話,Java是直接轉數組,kotlin中是轉list,需要toTypedArray()后轉數組
Java:
String str = "早,上,好"; String[] msg = str.split(",");
kotlin:
String str = "早,上,好"; val msg = str.split(",").toTypedArray()
也就是說 分割字符串轉list,kotlin只需要 val list= str.split(",") 即可