Lambda表达式和内部类
避免匿名内部类定义过多
让代码看起来更加简洁
函数式编程
总结
lambda表达式,只能有一行代码的情况下才能简化成为一行,如果有多行,那么就用代码块包含;
前提是接口为函数式接口;
多个参数,也可以去掉参数类型,要去掉就都去掉,必须加上括号;
内部类
通过理解内部类的各种写法,来推导Lambda表达式
package DemoTherad.Demo04;
//推导lamda表达式
public class TestLamda1 {
//3.静态内部类
static class Like2 implements ILike{
@Override
public void lamda() {
System.out.println("i like lamda2 静态内部类");
}
}
public static void main(String[] args) {
ILike like = new Like();
like.lamda();
ILike like2 = new Like2();
like2.lamda();
//4.局部内部类 定义在方法内部
class Like3 implements ILike{
@Override
public void lamda() {
System.out.println("i like lamda3 局部内部类");
}
}
ILike like3 = new Like3();
like3.lamda();
//5.匿名内部类,没有类的名称,必须借助接口,或者父类
ILike like4 = new ILike() {
@Override
public void lamda() {
System.out.println("i like lamda4 匿名内部类");
}
};
like4.lamda();
//6.用lambda 简化
ILike like5 = ()->{
System.out.println("i like lamda5 Lambda表达");
};
like5.lamda();
}
}
//1定义一个函数式接口,任何接口,只包含唯一一个抽象方法,他就是函数式接口
interface ILike{
void lamda();
}
//2实现类
class Like implements ILike{
@Override
public void lamda() {
System.out.println("i like lamda 实现类");
}
}
常规内部类
文件名叫做Outer I n n e r . c l a s s ∗ ∗ , 带 了 一 个 Inner.class**,带了一个 Inner.class∗∗,带了一个符号,这个特点让我们很容易的认出来这是内部类编译后的class文件**
- 内部类就像一个实例成员一样存在于外部类中;
- 内部类可以访问外部类的所有成员就像访问自己的成员一样没有限制;
- 内部类中的this指的是内部类的实例对象本身,如果要用外部类的实例对象就可以用类名.this的方式获得;
- 内部类对象中不能有静态成员,原因很简单,内部类的实例对象是外部类实例对象的一个成员;
常规内部类的创建方法
- **在外部类的内部,**可以用Inner inner = new Inner(); 方法直接创建;
- 在外部类外部,必须先创建外部类实例,然后再创建内部类实例;
- 除了上面 Inner inner = new Outer().new Inner()的写法以外;
- 还有 Outer outer = new Outer(); Inner inner = outer.new Inner();的写法;
局部内部类
把类定义在方法内部,称之为局部内部类
-
局部内部类的地位和方法内的局部变量的位置类似,因此不能修饰局部变量的修饰符也不能修饰局部内部类,譬如public、private、protected、static、transient等;
-
局部内部类只能在声明的方法内是可见的,因此定义局部内部类之后,想用的话就要在方法内直接实例化,记住这里顺序不能反了,一定是要先声明后使用,否则编译器会说找不到;
class Inner{ ... void print(){ ... Inner inner = new Inner(); //在局部内部类的方法中直接实例化 } ... }
-
局部内部类不能访问定义它的方法内的局部变量,除非这个变量被定义为final ;
匿名内部类
当我们把内部类的定义和声明写到一起时,就不用给这个类起个类名而是直接使用了,这种形式的内部类根本就没有类名,因此我们叫它匿名内部类;
package DemoTherad.Demo04;
//匿名内部类理解 接口
public class Test2 {
public interface Pet {
void beFriendly();
void play();
}
public static void main(String[] args) {
Pet test2 = new Pet() {
@Override
public void beFriendly() {
System.out.println("蹭蹭你^_^");
}
@Override
public void play() {
System.out.println("把飞盘叼给你,逼你把飞盘丢出去,然后它再捡回来让你继续扔,连续500次^_^");
}
};
test2.beFriendly();
test2.play();
}
}
- 匿名内部类可以是个接口;
- Pet test2 = new Pet() 后面是一段语句,就是定义了一个对象,因此大括号后面有个分号;
- 匿名内部类用 new Pet(){ … } 的方式把声明类的过程和创建类的实例的过程合二为一;
- 匿名内部类可以是某个类的继承子类也可以是某个接口的实现类;
方法参数内的匿名内部类
换句话说就是: 匿名内部类可以作为方法的参数
package DemoTherad.Demo04;
//匿名内部类可以作为方法的参数
public class Test3 {
static abstract class Ball {
abstract String getName();
}
void play(Ball b) {
System.out.println(b.getName());
}
public static void main(String[] args) {
Test3 dog = new Test3();
dog.play(new Ball() {
@Override
String getName() {
return "qiu qiu";
}
});
}
}
这个方法的参数就由一个匿名内部类的实例来提供
静态嵌套类
也可以理解为,静态内部类,需要加static修饰符;
因为静态嵌套类和其他静态方法一样只能访问其它静态的成员,而不能访问实例成员;
因此静态嵌套类和外部类(封装类)之间的联系就很少了,他们之间可能也就是命名空间上的一些关联;