zoukankan      html  css  js  c++  java
  • kotlin语法使用笔记

    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(",") 即可

  • 相关阅读:
    Jenkins忘记用户名密码怎么登陆,Tomcat启动Jenkins服务
    robotframework-ride导入已安装的库报红解决
    robotframework-ride打开提示wxPython不存在,实际已安装
    .NET开发Windows服务
    Hadoop:操作 Hadoop Cluster
    Hadoop: Hadoop Cluster配置文件
    Hadoop:部署Hadoop Single Node
    CentOS7安装ftp服务器
    理解timestamp
    python生成器实现杨辉三角
  • 原文地址:https://www.cnblogs.com/Sharley/p/10481914.html
Copyright © 2011-2022 走看看