内部类
内部类
内部类的作用:
每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响
内部类可以定义为接口,并且可以定义另外一个类来实现它
内部类可以定义为抽象类,可以定义另外一个内部类继承它
内部类的分类:
- 内部类定义在成员位置上:成员内部类
- 内部类定义在局部位置上:局部内部类
- 没有名字的内部类: 匿名内部类
- 被static修饰的内部类:
//成员内部类 //外部类 public class OuterClass { private String name; private int age; // 成员内部类可以直接使用外部类的成员变量 public class InnerClass { // 内部类的构造方法 public InnerClass() { name = "jack"; // 外部类的成员变量赋值 age = 12;// 外部类的成员变量赋值 } // 内部类的方法 public void display() { System.out.println("name=" + name + " age=" + age); } } public static void main(String[] args) { OuterClass outer = new OuterClass(); // 1.外部类的对象 OuterClass.InnerClass inner = null;// 2.以外部类.内部类的形式进行声明 inner = outer.new InnerClass(); // 3.以外部类对象.new 内部类构造方法()的方式构建对象 inner.display(); // 调用内部类的方法 } }
-
内部类的实例化是由外部类实例化之后才加载的,如果外部类还没有实例化,这时候调用内部类的静态成员,此时内部类还没有被加载,却要开始创建静态成员,显示是不合理的,
所以内部类中不能使用静态方法
-
成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类
//局部内部类 //外部类 public class OuterClass1 { private String name; //成员变量 private int age;//成员变量 //外部类的成员方法 public void display(int age1) { //局部内部类写在局部--方法里 class InnerClass{ //内部类的构造方法 public InnerClass() { name = "jack"; age = age1; //可以调用外部类的成员变量,也可以调用成员方法的局部变量(方法的参数,常量等) } //内部类的显示方法 public void display() { System.out.println("name="+name+" age="+age); } } InnerClass inner = new InnerClass();//创建内部类对象 inner.display(); //调用内部类中的display方法 } public static void main(String[] args) { OuterClass1 outer = new OuterClass1(); //创建外部类对象 outer.display(13); //调用外部类的成员方法 } }
静态内部类:
-
它的创建是不需要依赖于外部类的
-
它不能使用任何外部类的非static成员变量和方法
-
和成员内部类不同,static内部类
//外部类 public class OuterClass2 { //静态成员变量 private static String name ="jim"; //外部类静态成员变量,所以new 对象共享静态成员变量,外部类名.静态成员变量 //成员变量 private int age; //定义静态内部类 static class InnerClass{ //静态内部类成员变量 static String innerStaticName ="jack";//静态内部类的 静态成员变量 int innerAge; static void InnerStaticDisplay(){ //静态方法能够调用静态成员变量 System.out.println("静态内部类的静态方法InnerStaticDisplay被触发,innerStaticName="+innerStaticName); } void innerDisplay(){ //非静态方法可以调用静态和非静态成员变量 System.out.println("静态内部类的非静态方法innerDisplay被触发,innerStaticName="+innerStaticName+",innerAge"+innerAge); } } //外部类的成员方法 void outerDisplay(){ //外部类的方法可以调用静态内部类的静态成员变量 System.out.println(InnerClass.innerStaticName); //外部类的方法可以调用静态内部类的静态成员方法 InnerClass.InnerStaticDisplay(); } public static void main(String[] args) { OuterClass2 outer =new OuterClass2(); outer.outerDisplay(); //创建静态内部类对象 直接new静态内部类构造方法,不依赖outer对象 OuterClass2.InnerClass innerClass =new OuterClass2.InnerClass(); innerClass.innerDisplay(); //调用静态内部类的静态方法 OuterClass2.InnerClass.InnerStaticDisplay(); } }
//外部类 public class OuterClass3 { private int i=10; //外部类的成员变量 //成员内部类 public class InnerClass { private int i=100;//内部类的成员变量 void display(){ System.out.println(this.i);//内部类的成员变量 ,this指定是内部类的对象范围 System.out.println(OuterClass3.this.i);//外部类的成员变量i 外部类名.this 外部的对象引用 } } public static void main(String[] args) { //1.创建外部类对象 OuterClass3 outer =new OuterClass3(); //2.创建内部类对象 OuterClass3.InnerClass inner =outer.new InnerClass(); //3.调用内部类对象的display方法 inner.display(); } }
匿名内部类:
public interface Foo { void display(); } public class OuterClass4 { private String name; private int age; //创建 实现Foo接口对象,赋值给foo成员变量 Foo foo=new Foo() { @Override public void display() { System.out.println("实现Foo接口匿名类,display方法被调用"); } }; //创建继承OuterClass2匿名类的对象 赋值给outerClass2 成员变量 OuterClass2 outerClass2 =new OuterClass2(){ public void outerDisplay(){ System.out.println("重写OuterClass2.outerDisplay方法"); } }; public static void main(String[] args) { OuterClass4 outer =new OuterClass4(); outer.foo.display(); outer.outerClass2.outerDisplay(); } }
-
-
匿名内部类要想完成一些初始化工作可以交由类初始化或实例初始化代码块来完成
-
-
-
lambda语法结构:
lambda表达式的基本组成由 参数列表、->、方法体(单句时可不加大括号) 三部 分组成
(参数类型 参数名称) -> {
业务代码块
lambda表达式的重要特征:
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
1. 不需要参数,返回值为 5 :() -> 5
interface A{ int ma(); } public class LambdaTest { public static void main(String[] args) { test01(); } static void test01(){ /*A a =new A() { @Override public int ma() { return 5; } };*/ A a=()->5; System.out.println(a.ma()); } }
2.接收一个参数(数字类型),返回其2倍的值: x -> 2 * x
interface B{ int ma(int x); } public class LambdaTest { ...... static void test02(){ /*B a=new B() { @Override public int ma(int x) { return 2*x; } };*/ B b=x->2*x; System.out.println(b.ma(10)); } ...... }
3.接受2个参数(数字),并返回他们的差值: (x, y) -> x – y
interface C{ int ma(int x,int y); } public class LambdaTest { ...... static void test03(){ /* C a=new C() { @Override public int ma(int x, int y) { return x-y; } };*/ C c=(x,y)->x-y; System.out.println(c.ma(20,10)); } ...... }
3.接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void): (String s) -> System.out.print(s)
interface D{ void ma(String s); } public class LambdaTest { ...... static void test03(){ /* D a=new D() { @Override public void ma(String s) { System.out.println(s); } };*/ D d=s-> System.out.println(s); d.ma("Hello World"); } ...... }
4.用于替代匿名内部类的Lambda表达式例子
interface E{ void display(); } public class AnonymousInnerClass { private String name="Jerry"; private int age=24; /*E e=new E() { @Override public void display() { System.out.println("name = " + name+",age = " + age); } };*/ E e=()-> System.out.println("name = " + name+",age = " + age); public static void main(String[] args) { AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass(); anonymousInnerClass.e.display(); } }
Lambda表达式对返回的实例类型的要求
可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定 达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果 发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的
@FunctionalInterface interface D{ void ma(String s); default public void foo(){//可以存在默认方法 System.out.println("默认方法"); } //void foo1();//需要实现的抽象方法不止一个,编译器报错 } public class LambdaTest { ...... static void test03(){ /* D a=new D() { @Override public void ma(String s) { System.out.println(s); } };*/ D d=s-> System.out.println(s); d.ma("Hello World"); } ...... }
重要实例:匿名内部类和
public interface TestService {
int mm=20; //相当于 public static final mm=20;
default void ma(){
System.out.println("TestService接口的ma方法");
}
void test();
}
public class Test { int a=10; public void test1() { //定义局部变量 int c=10; final int d =20; TestService service1 = new TestService() { @Override public void test() { System.out.println(a); a=a+2;//匿名类对象方法是可以修改和使用成员变量 System.out.println(c);//能使用局部变量(隐含的final) //c=c+2; //修改c变量值就报错,说明final System.out.println(d);//能够使用final的局部变量 //d=d+30;//不能修改final变量 System.out.println("匿名内部类对象实现test方法"); ma();//匿名内部类方法体内可以调用接口defalut方法(默认方法) System.out.println(TestService.mm); //匿名内部类的方法体内部定义变量,是可修改的 int ff =0; ff =ff+2; } }; service1.test(); System.out.println("====================="); int b = 12; //标准写法 TestService service2 = () -> { System.out.println(a); //lambda可以修改和使用成员变量 a=a+2; System.out.println(b); //能使的局部变量(隐含final) //b =b+2; //修改就报错,就说明b是隐含的final System.out.println("标准写法lambda实现的test方法"); //ma(); //lambda方法体内不能调用接口defalut方法(默认方法) System.out.println(TestService.mm); //lambda的方法体内部定义变量,是可修改的 int ff =0; ff =ff+2; }; } }
::操作符
::操作符主要用作静态方法、成员方法或构造方法的绑定
1.::绑定静态方法
public class Test1 { public static void main(String[] args) { // 把Integer的静态方法 valueOf 绑定给IntegerFactory的cInteger方法 // 调用factory.cInteger()相当于调用Integer.valueOf方法 IntegerFactory factory =Integer::valueOf; Integer integer =factory.cInteger("254"); System.out.println(integer); } }
2.绑定实例成员方法
public class Test2 { //定义成员方法 public void foo(){ System.out.println("Test2的foo方法"); } public static void main(String[] args) { //创建Test2对象 Test2 t=new Test2(); //把test2对象的foo方法绑定Foo接口的ifoo方法上,要求返回值和参数列表一致 Foo foo =t::foo; //调用foo.ifoo()方法 foo.ifoo(); } }
3.绑定构造方法
@FunctionalInterface public interface PersonFactory { Person create(String firstName,String lastName); public class Person { String firstName; String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public Person() { } public Person(String firstName) { this.firstName = firstName; } @Override public String toString() { return "Person{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + '}'; } public static void main(String[] args) { PersonFactory pf =Person::new;//把Person的构造方法绑定PersonFactory接口匿名类create方法上 Person p=pf.create("张","三"); System.out.println(p); } }

浙公网安备 33010602011771号