匿名内部类和lambd表达式

一.匿名内部类

匿名内部类是局部内部类的一种特殊形式,是一个没有类名的局部内部类

我们想实现一个抽象类的方法需要怎么做呢?让我们看下面的过程

  • 定义一个抽象类Person
    public abstract class Person {
        public abstract void sleep();
    }
  • 定义一个Student类继承Person,并重写sleep方法

public class Student extends Person{
    @Override
    public void sleep() {
        System.out.println("学生再睡");
    }
}
  • 创建Test类来写main方法进行测试
public class Test {
    public static void main(String[] args) {
        Person p = new Student();
        p.sleep();
    }
}

         完成的功能平平无奇,但是确需要写三个类,我们发现想要调用Person中的抽象方法sleep方法,就必须创建一个子类,然后创建一个子类的实例对象然后再去调用方法。这可谓是把java面向对象的思想体现的淋漓尽致,万物皆对象嘛,这是java的优点,可是对于我们实现一个简单的功能,需要创建这么多对象,我们或多或少会觉得有些复杂了,那么有没有什么方法能够简化这一过程呢?

         这就引出了我们这一部分的主角,匿名内部类。

我们使用匿名内部类如何实现上面的功能呢?

public static void main(String[] args) {
    Person p = new Person() {
        @Override
        public void sleep() {
            System.out.println("");
        }
    };
    p.sleep();
}

这就是匿名内部类,我们对这个结构进行下分析 

首先我们都知道抽象类是无法直接生成对象的,必须通过子类,但是通过代码我们能看到,这段代码在实现功能的过程中没有通过子类,而是通过

new Person{....};

来代替了new Student(),所以正常来说,这里应该是子类的位置,现在却通过父类实现了(我称其为以父之名)。

其次new Person{....};中的{....}实际是完成了Student子类中,对父类方法重写的过程,所以{....}被称为是类体

所以从理解角度来说 Person{....};是一个没有名字的子类,并且是在Tset内部的类,所以叫匿名内部类没毛病。

注:这里父类不一定要是抽象类,普通类和接口也可以,只要在匿名内部类中重写了父类方法即可

所以匿名内部类的使用前提是:必须继承—个父类或者实现—个接口

public static void main(String[] args) {
Person p = new Person() {
    @Override
    public void sleep() {
        System.out.println("学生在睡觉");
    }
};
Person p0 = new Person() {
    @Override
    public void sleep() {
        System.out.println("工人在睡觉");
    }
};
p0.sleep();
    
}

        可以看到这样一来,我们就不需要关心,到底需要哪个对象来调用方法,只需要关注,方法体完成的事情本身就可以了,这样就有点像是把面向对象的编程思想,缩回了面向过程的

        面向对象的方法固然好,因为我们的程序大部分是复杂的,大的东西,以后扩展,所以需要抽离出来会更加方便不可是总还是有一些事情,这些事情固然少可是总会有一些事情,就不会去变复杂去扩展,那我们就不需要去抽离,那就简单的面向过程就好了. 


二、lambda表达式

        函数式编程思想(面向过程),在数学中,函数是有输入量和输出量的一套计算方案,"就是那数据做操作",在面向对象的编程中强调必须用对象来做事情,函数式编程思想则尽量的忽略,对象的复杂语法,强调做什么,而不是以什么形式是去做,lambda就是函数是编程的具体体现

思考如何,启动一个线程,在控制台输出一句话,“多线程启动了”

方案1:

定义一个MyRunable的类,重写run方法

public class LambdaDemo{
    public static void main(){
        MyRunnable myRun
        nable = new MyRunnable();
        Thread t = new Tread(myRunnable);//线程类,必须实现了Runnable的接口的才是可以启动线程的
        t.start;        
    }
}
class MyRunnable impl;ements Runnable{
    public void run(){
        System.out.println("多线程启动了")    
    }
}

 方案二:

使用匿名内部类进行改进,省略了实现类,更注重于做事情

 public static void main(){
    Runnable run = new Runnable(){
             public void run(){
        System.out.println("多线程启动了") ;   
    }
     } ;
     Thread t = new Tread(run);//线程类,必须实现了Runnable的接口的才是可以启动线程的
        t.start;      
     
 }

 

方案三:

lambda表达式 /*不需要表现是谁做的*/ 

Thread t = new Tread(( [run方法的参数] ])->{
    System.out.println("多线程启动了") 
});
    t.start();

Thread t = new Tread(( )->{

System.out.println("多线程启动了")

});

t.start();

好这种写法看起来比匿名内部类还要简单,其实这是对匿名内部类的简化,初学者的话啊可以先写出匿名内部类形式,然后改写成lambda性质哦,

我们具体分析一下,Thread t = new Tread(...);这一部分中的...就是代替了实现Runnable类的对象

( )这个括号里面是public void run(),中的括号,是用来写方法参数的

->{

System.out.println("多线程启动了")

} 这一部分是方法体;

 

语法和要求

  • 三要素:形式参数,箭头,代码块
  • 格式:(形参)->代码块
  • 形参要求:如果有多个形参,形参以逗号隔开,如果没有参数,括号不能省略
  • ->由英文的中划线和大于号组成,这是固定写法表示执行
  • 代码块:是我们具体要做的事,就是方法体和内容
  • 使用前提:有一个接口,该接口只有一个抽象方法

示例1:无参无返回值

/*NoReturnNoParam 是一个接口
* 该接口只有一个方法method
*/
public interface NoReturnNoParam{
    void method();
}
NoReturnNoParam noReturnNoParam  = () -> {
     System.out.println("NoReturnNoParam") ;   
};
  

//调用方式
noReturnNoParam.method();  

示例2:有参无返回值

public interface NoReturnOneParam{
    void method(int a);
}
public interface NoReturnMultiParam{
    void method(int a,int b);
}
    NoReturnOneParam noReturnOneParam = (int a)->{
        System.out.println(a+10);
    };
    NoReturnMultiParam noReturnMultiParam = (int a,int b)->{
        System.out.println(a+b);
    };


noReturnOneParam.method(10); 
noReturnMultiParam.method(10,20); 

 示例3:有参有返回值

ReturnMultiParam returnMultiParam = (int a,int b) ->{
    return a+b;
};

System.out.println(returnMultiParam.method(30,30));I

 

  • 16
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值