精华内容
下载资源
问答
  • 扩展函数

    2015-09-29 20:18:08
    扩展函数  以下内容大部分来源于:http://www.cnblogs.com/sunrack/articles/1073759.html  http://blog.csdn.net/hu8hong9/article/details/1856026  1、在什么情况下使用  使用扩展函数,可以为...

    扩展函数

      以下内容大部分来源于:http://www.cnblogs.com/sunrack/articles/1073759.html

                 http://blog.csdn.net/hu8hong9/article/details/1856026

      1、在什么情况下使用

        使用扩展函数,可以为无法修改源代码的对象添加新的方法,或者强制让对象支持某些方法,这些方法看起来就是对象本来就有的功能。当我们在对类A的进行操作时,发现类A中没有某些方法,我们又不能对类A直接修改,但是我们又要用到该方法时,可以用扩展函数的功能新建一个类,并且创建要使用的方法。

       2、使用方法:

        声明扩展函数:扩展函数使用特定的关键字this作为修饰符应用于函数的第一个参数来声明。扩展函数只能声明在static的类中

        导入扩展函数:扩展函数通过using-namespace-directives 导入。另外导入的有,该namespace所包含的类型,using-namespace-directive 导入所有的扩展函数在该namespace中的所有static类。被导入的扩展函数有效地作为在某些类型上的额外函数,这是通过它们的第一个关键字以及比常规的实例函数更低的优先级所给与的。

        扩展函数的调用:如果正常的调用过程中没有发现适用的实例函数(尤其如果对此调用的候选函数为空的情况下),编译器将做出尝试将构造过程作为扩展函数来调用。

      3、限制条件

        1、必须在static class 中定义,所以必须使用static修饰
         2、需要在(只需要在)第一个参数前面使用this修饰
         3、扩展函数可以通过对象实例调用,也可以使用定义该函数的静态类直接调用

      4、简单的例子

        新建一个类:

    复制代码
    public static class E {
            public static string F(this object obj, int i)//扩展函数
            {
                return "E:"+i.ToString();
            }
    
            public static string F(this object obj, string s)
            {
                return "E:" + s;
            }
        }
        class A {//类A中没有方法
        }
        class B {
            public string F(int i)
            {
                return "B:" + i.ToString();
            }
        }
        class C {
            public string F(object obj)
            {
                return "C:" + obj.ToString();
            }
        }
    复制代码


    添加相应函数如下:

    复制代码
    //B的函数优先于前面的扩展函数,并且C的函数优先于所有的扩展函数。
            protected void Button1_Click(object sender, EventArgs e)
            {
                A a = new A();             //A中没有F()函数,将调用扩展函数
                Label1.Text=a.F(1);                         // E.F(object, int)
                Label1.Text +="<br/>"+ a.F("hello");     // E.F(object, string)
                
                B b = new B();             //B中有F(int),则调用此,没有对string的操作,调用扩展函数。
                Label1.Text += "<br/>" + b.F(1);              // B.F(int)
                Label1.Text += "<br/>" + b.F("hello");     // E.F(object, string)
    
                C c=new C();
                Label1.Text += "<br/>" + c.F(1);              // C.F(object)
                Label1.Text += "<br/>" + c.F("hello");     // C.F(object)
            }
    复制代码

     运行结果如下:

      5、使用范围

        扩展函数本质上是在被扩展的对象实例上可以调用的静态函数,不是继承,所以不同于普通的成员函数,扩展函数不能直接访问被扩展对象的成员。只能通过该对象的实例来访问。

      6、扩展接口类型

    在接口中必须给出方法的实现

    // Define a normal CLR interface in C#.
    interface IBasicMath
    {
    int Add(int x, int y);
    }
    // Implementation of IBasicMath.
    class MyCalc : IBasicMath
    {
    public int Add(int x, int y)
    {
    return x + y;
    }
    }

    但是,如果只是如下扩展,将会发生错误

    static class MathExtensions
    {
    // Extend IBasicMath with subtraction method?
    public static int Subtract(this IBasicMath itf,
    int x, int y);
    }

    必须给出函数的实现

    static class MathExtensions
    {
    // Extend IBasicMath this method and this
    // implementation.
    public static int Subtract(this IBasicMath itf,
    int x, int y)
    {
    return x - y;
    }
    }

    调用
    static void Main(string[] args)
    {
    Console.WriteLine("***** Extending an interface *****\n");
    // Call IBasicMath members from MyCalc object.
    MyCalc c = new MyCalc();
    Console.WriteLine("1 + 2 = {0}", c.Add(12));
    Console.WriteLine("1 - 2 = {0}", c.Subtract(12));
    // Can also cast into IBasicMath to invoke extension.
    Console.WriteLine("30 - 9 = {0}",
    ((IBasicMath)c).Subtract(309));
    // This would NOT work!
    // IBasicMath itfBM = new IBasicMath();
    // itfBM.Subtract(10, 10);
    Console.ReadLine();
    }

    扩展接口后,显然不能直接在接口上调用这些扩展函数,只能理解为,所有继承该接口的对象新增加了这些扩展函数功能,

    展开全文
  • 扩展函数作用域总结 : ① 扩展函数作用域 : 扩展函数使用需要导入包 , 如果在本包中使用 , 可以默认不导入包 ; ② 扩展函数可以重载 : 函数名相同 , 函数签名不同的扩展函数可以同时定义 , 导入包时导入一次即可...



    I . 扩展函数 作用域 总结



    扩展函数作用域总结 :


    ① 扩展函数作用域 : 扩展函数使用需要导入包 , 如果在本包中使用 , 可以默认不导入包 ;

    ② 扩展函数可以重载 : 函数名相同 , 函数签名不同的扩展函数可以同时定义 , 导入包时导入一次即可调用所有的重载的扩展函数 ;

    ③ 扩展函数作用域优先级 : 声明导入的扩展函数优先级高于默认包的优先级 , 声明导入哪个包就调用哪个包的扩展函数 ;



    II . 扩展函数 作用域



    1 . 扩展函数作用域 : 定义一个扩展函数 , 默认只能在本包中调用 , 如果在别的包调用扩展函数 , 需要导入扩展函数 ;


    2 . 扩展函数导入 : 调用接收者类型的扩展函数 , 需要导入扩展函数的包 , 导入格式为 :

    import 包名.扩展函数名
    

    3 . 调用定义在本包里的扩展函数 : 可以直接调用 , 导入扩展函数的操作可以省略 , 写上也不会出错 ;


    4 . 调用定义在其它包的扩展函数 : 必须导入扩展函数 , 才能调用该扩展函数 ;



    III . 扩展函数 作用域 简单调用示例



    1 . 分别在 本包 和 外包 中定义扩展函数 :


    ① 本包定义扩展函数 : 普通的扩展函数定义 , 在 extendbean 包的文件下定义 Student 类 , 在 extendbean 包的文件下定义 Student 类的扩展函数 ;

    package extendbean
    
    class Student {
        var name : String = "Tom"
        var age : Int = 18
    }
    
    //在同一个文件中扩展
    fun Student.printName(){
        println("${this.name}")
    }
    

    ② 外包定义扩展函数 : 外包中定义 Student 类的扩展函数 , 自然需要导入 Student 类 ;

    package extenddeclare
    
    import extendbean.Student
    
    //定义扩展函数
    fun Student.printNameAndAge(){
        println("${this.name} , ${this.age}")
    }
    


    2 . 本包 中调用扩展函数 :


    ① 代码分析 : 在 extendbean 包中调用 extenddeclare 包中的为 Student 扩展的 printNameAndAge 函数 , 需要使用 import extenddeclare.printNameAndAge 导入该扩展函数 ;

    package extendbean
    
    //本包中可以不同导入 Student 包
    //import extendbean.Student
    
    //在本包内定义的扩展函数就不需要导入包了
    //import extendbean.printAge
    //import extendbean.printName
    
    //使用 Student 的扩展 , 也需要导入 扩展函数所在包名.扩展函数名
    import extenddeclare.printNameAndAge
    
    fun main() {
        var student : Student = Student()
        student.printNameAndAge()
        student.printName()
    }
    

    ② 执行结果 :

    Tom , 18
    Tom
    


    3 . 外包 中调用扩展函数 :


    ① 代码分析 : 在 extendusage 包中调用 extendbean 包中的 Student 类 和 扩展函数 , 以及 extenddeclare 包中定义的 printNameAndAge 扩展函数 , 需要将 Student 类以及所有的扩展函数都声明导入 , 才可以使用 ;

    package extendusage
    
    //使用到 Student 需要导入该类的包
    import extendbean.Student
    
    //使用 Student 的扩展 , 也需要导入 扩展函数所在包名.扩展函数名
    import extendbean.printName
    import extenddeclare.printNameAndAge
    
    fun main() {
        var student : Student = Student()
        student.printNameAndAge()
        student.printName()
    }
    

    ② 执行结果 :

    Tom , 18
    Tom
    


    IV . 扩展函数 重载分析



    1 . 包内禁止定义相同函数签名的扩展函数 : 在同一个包里 , 定义了一个扩展函数后 , 不允许定义相同函数签名的扩展函数 ; 不管是定义在同一个文件中 , 还是不同的文件中 , 函数签名不可以重复 ;

    在这里插入图片描述


    2 . 原理分析 : 因为扩展函数是根据 包名.扩展函数名 识别的 , 如果在同一个包内定义了相同函数签名的扩展函数 , 无法识别应该调用哪个扩展函数 ;


    3 . 重载说明 : 扩展函数在同一个包内 , 可以进行重载操作 , 即定义函数名相同 , 参数列表和返回值类型或顺序不同的函数 , 两个同名函数签名不同 , 因此可以区分调用 ;

    在这里插入图片描述



    V . 扩展函数 重载代码示例



    1 . 重载扩展函数导入 : 对于重载的扩展函数 , 可以导入一次包即可通过函数签名调用不同的扩展函数 ;


    2 . 定义重载扩展函数 : 为 Student 扩展了两个函数 , 分别是 printName() 和 printName(num : Int) , 这两个函数签名不同 , 可以定义 , 调用时根据不同的函数签名分别调用 ;

    package extendbean
    
    class Student {
        var name : String = "Tom"
        var age : Int = 18
    }
    
    //在同一个文件中扩展
    fun Student.printName(){
        println("${this.name}")
    }
    
    //测试重载的函数可以只声明一次
    fun Student.printName(num : Int){
        println("${this.name}")
    }
    

    3 . 调用重载扩展函数 : 根据不同的函数签名调用不同的扩展函数 ;

    package extendbean
    
    fun main() {
        var student : Student = Student()
        student.printName()
        student.printName(10)
    }
    

    4 . 执行结果 :

    Tom
    name : Tom , num : 10
    


    VI . 扩展函数 作用域 优先级 分析



    本节讨论的是在不同包定义的相同函数签名的扩展函数调用问题


    1 . 不同的包可以定义相同函数签名的扩展函数 : 在不同的包内 , 可以定义相同函数签名的扩展函数 , 调用时需要考虑各种情况 ; 其导入包的扩展函数优先级较高 , 没有发现导入包 , 才会去默认的本包中查找是否有定义该签名的扩展函数 ;


    2 . 情况 一 : 在包内调用本包和外包的 相同签名的 扩展函数 ;

    ① 导入的包优先级高 : 如果导入外包扩展函数 , 就会调用外包的扩展函数 ;

    ② 本包默认优先级较低 : 如果没有导入 , 就会默认调用本包定义的的扩展函数 ;


    3 . 情况 二 : 在一个包中调用 其它两个包 的 相同签名的 扩展函数 ;

    ① 调用优先级 : 导入哪个包 , 就调用哪个包的扩展函数 ;

    ② 重复导入 : 两个包都导入会报错 ;

    在这里插入图片描述



    VII . 扩展函数 作用域 优先级 代码示例分析



    1 . 不同包中定义相同函数签名的扩展函数 : 为 Student 类在不同的包中定义相同函数签名的扩展函数 ;


    ① 在 extendbean 包定义了 Student.printNameAndAge() 扩展函数 :

    package extendbean
    
    class Student {
        var name : String = "Tom"
        var age : Int = 18
    }
    
    //定义扩展函数
    fun Student.printNameAndAge(){
        println("${this.name} , ${this.age}")
    }
    

    ② 在 extenddeclare 包也定义了相同函数签名的 Student.printNameAndAge() 扩展函数 :

    package extenddeclare
    
    import extendbean.Student
    
    //定义扩展函数
    fun Student.printNameAndAge(){
        println("${this.name} , ${this.age}")
    }
    


    2 . 在 extendbean 包中调用扩展函数分析 :


    ① 没有导入 extenddeclare.printNameAndAge 包 : 直接根据函数签名调用扩展函数 , 此时调用的是本包中定义的扩展函数 ;

    package extendbean
    
    //使用 Student 的扩展 , 也需要导入 扩展函数所在包名.扩展函数名
    //import extenddeclare.printNameAndAge
    
    //此处注释掉了导入包的操作
    
    fun main() {
        var student : Student = Student()
        student.printNameAndAge()
    }
    

    执行结果 : 根据结果可以看到 , 调用的是 extendbean 包中的扩展函数 ;

    extendbean : Tom , 18
    

    ② 导入了 extenddeclare.printNameAndAge 包 :

    package extendbean
    
    //使用 Student 的扩展 , 也需要导入 扩展函数所在包名.扩展函数名
    import extenddeclare.printNameAndAge
    
    fun main() {
        var student : Student = Student()
        student.printNameAndAge()
    }
    

    执行结果 : 根据结果可以看到 , 调用的是 extenddeclare 包中的扩展函数 ;

    extenddeclare : Tom , 18
    


    2 . 在 extendusage 包中调用扩展函数分析 : 这是个第三方包 , 分别在 extendbean 和 extenddeclare 定义了两个相同函数签名的 Student 扩展函数 ;


    ① 声明哪个包就调用对应包的方法 : 此时声明导入的是 extendbean.printNameAndAge , 就会调用 extendbean 包下的扩展函数 ;

    package extendusage
    
    //使用到 Student 需要导入该类的包
    import extendbean.Student
    
    import extendbean.printNameAndAge
    //import extenddeclare.printNameAndAge
    
    fun main() {
        var student : Student = Student()
        student.printNameAndAge()
    }
    

    执行结果 :

    extendbean : Tom , 18
    

    ② 如果都声明报错 : 如果两个包都声明 , 会如下错误 Overload resolution ambiguity. All these functions match. ;

    在这里插入图片描述

    展开全文
  • kotlin扩展函数

    千次阅读 2020-04-17 15:23:18
    如果说java是开发android的绿皮车,那么kotlin就像是开发android的动车高铁,至于为什么这么说,其中的原因之一:扩展函数 至于什么是扩展函数,本文不做过多的介绍,不懂的,需要补基础的可以找某度,本文只介绍...

    简介

    如果说java是开发android的绿皮车,那么kotlin就像是开发android的动车高铁,至于为什么这么说,其中的原因之一:扩展函数

    至于什么是扩展函数,本文不做过多的介绍,不懂的,需要补基础的可以找某度,本文只介绍怎么使用,有多方便自己体验。

    使用结构如下图,其中ActivityExtends,ContextExtends,ImageViewExtends都是扩展函数
    在这里插入图片描述
    罗列其中的几个功能作为演示

    1、在activity或者fragment中弹出菊花等待加载框(背景半透明)

    fun Activity.showProgressDialog(context: Context) {
        var mAlertDialog = AlertDialog.Builder(context, R.style.CustomProgressDialog).create()//去除AlertDialog的背景透明
        val loadView = LayoutInflater.from(context).inflate(R.layout.dialog_progressbar_juhua, null)//默认的红色转圈,这里改成自己定义的菊花旋转
        mAlertDialog!!.setView(loadView, 0, 0, 0, 0)
        //        mAlertDialog.setCanceledOnTouchOutside(false);//随便点一下屏幕其他是否消失
        mAlertDialog!!.setCanceledOnTouchOutside(true)//随便点一下屏幕是否消失
        mAlertDialog!!.show()
    }
    

    在activity中怎么使用:

    showProgressDialog(this)
    

    CustomProgressDialog ,dialog_progressbar_juhua这两个同学们自己定义

    2、加载网络图片到imageview

    implementation ‘com.github.bumptech.glide:glide:4.7.1’

    /**
     * 加载圆形图片
     */
    fun ImageView.loadCircleImage(context: Context, path: String, placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean = false) {
        var options = getOptions(placeholder, useCache)
        options.circleCrop()
        Glide.with(context).load(path).apply(options).into(this)
    }
    private fun ImageView.getOptions(placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean = false): RequestOptions {
        var options = RequestOptions()
        options.placeholder(placeholder)
        options.priority(Priority.HIGH)
        if (useCache)
            options.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        return options
    }
    

    在activity中怎么使用:

    //iv_1是imageview的id
     iv_1.loadCircleImage(this, "图片url")
    

    3、在activity或者fragment中弹出提示用户的对话框

    fun Context.showAlertDialog(
            title: String,
            message: String,
            ok: Pair<String,()->Unit>,
            cancel: Pair<String,()->Unit>? = null){
    
        val builder = AlertDialog.Builder(this)
                .setTitle(title)
                .setMessage(message)
                .setCancelable(false)
                .setPositiveButton(ok.first) { _,_ -> ok.second() }
    
        cancel?.let{
            builder.setNegativeButton(it.first) { _, _ -> it.second() }
        }
    
        builder.create().show()
    }
    

    在activity中怎么使用:

                showAlertDialog(
                        title = "我是标题",
                        message = "我是提示的内容",
                        ok = "Yes" to { test()//点了yes后需要运行的方法},
                        cancel = "No" to { finish() }
                )        
    

    这3个示范是从我自己练习的项目中提取出来,都是可以运行的,希望大家喜欢

    还需要实现的功能:Toast,加载框,权限申请,跳转和带参数跳转,沉浸式状态栏(背景,文字)

    展开全文
  • kotlin随笔—扩展函数

    千次阅读 2017-01-09 17:04:43
    扩展函数

    扩展函数

    1、简介

    • Kotlin的扩展函数功能使得我们可以为现有的类添加新的函数,实现某一具体功能 。
    • 扩展函数是静态解析的,并未对原类添加函数或属性,对类本身没有任何影响。
    • 扩展属性允许定义在类或者kotlin文件中,不允许定义在函数中。

    2、定义形式

    lambda是要作为参数被传入某方法或赋值给某变量的匿名方法的简化表现形式。

    fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){

        Toast.makeText(this, message, duration)
.show()
    }
    • Activity:表示函数的接收者,也就是函数扩展的对象
    • . :扩展函数修饰符
    • toast:扩展函数的名称
    • (...):扩展函数的参数,可以为null

    Activity的类中可以直接使用toast()方法,eg、toast("this is toast")。这就是对Activity类的扩展。

    3、扩展函数中this关键字

    this指接收者对象(receiver object)(也就是调用扩展函数时, 在"."号之前指定的对象实例).

    fun Any?.toString():String{
        if(this == null)
            return "null"
        else{
            return toString()
        }
    }

    对象有可能为空,为空时,返回"null",而不是抛出NullPointException。

    展开全文
  • Kotlin系列之扩展函数

    万次阅读 2018-04-17 00:22:18
    简述: 今天带来的是Kotlin浅谈系列的第五弹,这讲主要是讲利用Kotlin中的扩展函数特性让我们的代码变得更加简单和整洁。扩展函数是Kotlin语言中独有的新特性,利用它可以减少很多的样板代码,大大提高开发的效率;...
  • 一、扩展函数和扩展属性  1.1、扩展函数  扩展函数用于为一个类增加一种新的行为,这是为缺少有用函数的类进行扩展的途径。扩展函数的用途就类似于在 Java 中实现的静态工具方法。而在 Kotlin 中使用扩展函数的...
  • 文章目录扩展函数和扩展属性的实现为什么要用扩展函数和扩展属性学习交流 扩展函数给本来单薄的类添加了许多功能,今天我们来详细看一下扩展函数和扩展属性到底是什么,应该怎么用。 扩展函数和扩展属性的实现 我们...
  • kotlin的扩展函数和扩展属性

    千次阅读 2017-06-01 17:38:16
    扩展函数与扩展属性的神奇之处在于,可以在不修改原来类的条件下,使用函数和属性,表现得就像是属于这个类的一样。下面我们先看使用效果1.扩展属性第一个红矩形框中,你会发现TextView什么时候有leftMargin这个属性...
  • jQuery扩展函数方法

    2016-08-18 14:23:16
    jQuery扩展函数 //$.extend({}) 是扩展jQuery这个类,为jQuery添加新的方法 //写法一 ;(function($){ $.extend({ zhao:function(){ alert("这是我的第一个扩展函数"); },
  • 今天,让我们聊聊Kotlin中的扩展函数和属性的话题。 扩展函数和属性,见名知意,就是可以做到在目前已存在的类的基础上添加函数和属性,只是这些函数和属性定义在类的外部,是不是很好奇呢?那就一起来看看吧。 ...
  • android kotlin扩展函数

    2017-06-07 11:00:36
    Kotlin的扩展函数功能使得我们可以为现有的类添加新的函数,而不用修改原来的类。这可以帮助我们简化代码而且让封闭的类打破局限.这些函数通常会替代工具类。示例:fun intMult(num: Int): Int { return num * 2}...
  • Kotlin之扩展函数

    千次阅读 2018-09-11 17:59:52
    在介绍扩展函数之前,我们先简单介绍一下变量和属性: 变量 变量通常可以改变的,常量是不可改变的.例如java中的final修饰的变量就是常量不可改变的. 在kotlin中我们用val和var来修饰,val修饰的变量是不可变变量,...
  • C# - 扩展函数

    千次阅读 2015-04-16 16:07:43
    使用扩展函数,可以为无法修改源代码的对象添加新的方法,或者强制让对象支持某些方法,这些方法看起来就是对象本来就有的功能。 二、限制条件 1、必须在static class 中定义,所以必须使用static修饰 2、需要...
  • Kotlin 扩展函数详解与应用

    千次阅读 2017-08-16 07:32:18
    一、什么是扩展函数扩展函数数是指在一个类上增加一种新的行为,甚至我们没有这个类代码的访问权限。这是一个在缺少有用函数的类上扩展的方法,Kotlin能够为我们做到那些令人关注的事情,而这些Java做不到。在Java...
  • Kotlin扩展函数与重载操作符解析

    千次阅读 2017-06-15 17:58:06
    扩展函数可以称为Kotlin的核心,标准库里到处充斥着扩展函数和高阶函数。然而标准库中扩展函数看起来都是高深莫测,一脸懵逼。本文教你如何理解扩展函数
  • 扩展函数在Kotlin中有着重要的应用,我们使用的Kotlin为我们提供的许多方便的方法都是通过扩展方法实现的,那么扩展函数究竟长啥样呢?我们来看看所谓扩展,即能过扩展一个类的新功能而无需继承或使用像装饰者这样的...
  • 求大神 问一下, 在做扩展函数的时候,我在一个class中定义了一个方法,但是在别的class中不能调用这个方法,我看资料显示,可以在任何地方调用的,不知道是怎么回事
  • kotlin动态批量获取权限的扩展函数

    千次阅读 2020-05-12 11:28:01
    动态批量获取权限的扩展函数 简介 每个app必定都需要使用到获取权限的功能,所以把这个做成扩展函数是必要的,方便,而且随时可以调用。 这篇文章是关于批量的获取用户权限的功能。 运行图片: 代码 manifest.xml ...
  • Kotlin 真香系列:扩展函数和属性

    千次阅读 2020-05-28 09:43:25
    本文将介绍 Kotlin 中的扩展函数和扩展属性,并用这两个特性来逐步优化代码的写法,希望大家学习这种特性并在实践当中做更多的扩展。
  • ThinkPHP的扩展函数库中有对中文字符串进行截取的函数 扩展函数库的方法不能直接使用,需要加载或者拷贝到项目函数库中才能使用。 加载扩展函数库,使用: Load('extend'); 加载扩展函数库后,就可以...
  • 一、扩展方式对扩展函数的影响 Kotlin是一种静态类型语言,我们创建的每个对象不仅具有运行时,还具有编译时类型,开发人员必须明确指定(在Kotlin中可以判断)。在使用扩展函数时,要清楚地了解静态调用和动态调用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,636
精华内容 22,654
关键字:

扩展函数