今日目标: 1能够创建四种内部类 2能够知道每种内部类的特点和应用 3能够熟练使用匿名内部类 4lambda表达式的基本使用 5能够学会匿名内部类和lambda表达式的转换一内部类成员内部类1。1问题提问:1。什么是内部类2。如何创建内部类对象3。内部类的访问特点1。3问题答案:1。什么是内部类定义在一个类中的类2。如何创建内部类对象外部类对象。内部类对象对象名new外部类对象()。new内部类对象();3。内部类的访问特点内部类可以直接访问外部类的成员,包括私有成员。外部类想要访问内部类的成员,必须先创建对象。1。4内部类详细说明1内部类:其实并不是什么地方都能用上2内部类分类:成员内部类静态内部类局部内部类匿名内部类3语法:类中定义类classA{classB{B就是A的内部类编译之后会生成两个class文件A。classAB。class说明内部类只是在编译期有效到运行期A和B是没有包含关系是两个相互独立的类所以内部类仅仅是一个编译期的语法外部类名称内部类名称。class}}4作用:1防止类名冲突同一个包内定义两个同名的类是不允许的但是可以创建同名的内部类publicclassDemo1{}classB{classDemo1{}}2实现多继承classAextends类名{classBextends类名{还是单继承但是内部内部可以访问外部类的所有属性和方法包括私有}}3内部类可以很好的实现隐藏:一般的非内部类,是不允许有private与protected权限的,但内部类可以所以内部类往往都定义了企业最核心的逻辑代码5缺点:使程序结构不清晰。二静态内部类2。1问题提问1内部类能被私有吗2外部类如何使用私有内部类2静态内部类的创建格式2。3问题答案1内部类能被私有吗可以被private修饰只能在自己所在的外部类中去访问2可以在外部类中创建方法在方法中去使用私有内部类3静态内部类的创建格式外部类。内部类对象名new外部类。内部类();静态内部类中的静态成员访问格式外部类。内部类。成员2。4成员内部类详解注意点:1成员内部类和成员属性定义位置一样2成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)3创建成员内部类必须先创建外部类对象,通过外部类对象。new构造内部类对象4成员内部类中不能有静态成员5当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类。this。成员变量外部类。this。成员方法6成员内部类可以有常量代码演示classOuter{privateinta100;publicOuter(inta){this。aa;}publicvoidmethod(){InnerinnewInner();in。print();}Inner的定义位置是Outer类的成员位置上是内部类可以用privatepublic修饰里边和正常定义类一样classInner{inta20;publicvoidprint(){那能不能打印a,a的作用范围是整个Outer类所以是可以打印的inner在Outer类的封装范围内System。out。println(a);使用外部类的同名aSystem。out。println(Outer。this。a);}staticintb10;内部类不能有静态成员finalintB210;可以有常量staticfinalintB110;可以有静态常量}}}问题思考:为什么成员内部类不能有静态成员?JVM的类加载规则:1。static类型的属性和方法,在类加载的时候就会存在于内存中。2。要想使用某个类的static属性和方法,那么这个类必须要加载到JAVA虚拟机中。3。非静态内部类并不随外部类一起加载,只有在实例化外部类之后才会加载。publicclassOuter{intx;classInner{staticinta0;这样写是不合法的。staticfinalintb0;这样写是合法的}}java类加载顺序,首先加载类,执行static变量初始化,接下来执行对象的创建,如果我们要执行代码中的变量inta初始化,那么必须先执行加载外部类,再加载内部类,最后初始化静态变量a,问题就出在加载内部类上面,我们可以把内部类看成外部类的非静态成员,它的初始化必须在外部类对象创建后以后进行,要加载内部类必须在实例化外部类之后完成,java虚拟机要求所有的静态变量必须在对象创建之前完成,这样便产生了矛盾。将classInner看作外部类的非静态成员,它属于对象Outer(即new出来的Outer()),staticinta属于类Inner所以先于对象InnerOuter创建出来,矛盾而java常量放在内存中常量池,它的机制与变量是不同的,编译时,加载常量是不需要加载类的,所以就没有上面那种矛盾。静态的东西需要在编译时分配内存,而非静态内部类是在实例化的时候才分配内存。所以现在的情况就是有了东西没地方放staticinta没地方放,因为classInner还没有实例化问题思考:为什么内部类能访问外部类的成员因为内部类持有外部类的引用classOuter{privateinta100;classInner{intb20;publicvoidprint(){System。out。println(b);this。bSystem。out。println(a);Outer。this。a}}}总结内部类1名义上内部类实际上是外部类,每个内部类都有自己独立的。class文件命名外部类内部类。class2封装性更高可以作成私有内部类往往都定义了企业最核心的内容3大多数情况下内部类的对象都是由外部类去创建的(也就是说在外部类中new内部类对象)4成员内部类能够持有外部类的this5内部类不会在外部类初始化的时候被初始化2。5静态内部类详解和静态成员定义位置一样静态内部类只能访问外部类的静态成员所以不再需要先创建外部类对象classOuter{privateinta10;privatestaticintb20;publicOuter(){System。out。println(out);}publicvoidmethod1(){Inner。mehtod();外部类可以直接调用内部类的静态方法和属性intbInner。a;System。out。println(outer普通方法);}publicstaticvoidmethod2(){System。out。println(outer静态方法);}staticclassInner{staticinta20;publicInner(){System。out。println(in);}publicvoidprint(){System。out。println(a);静态内部类只能访问外部类的静态成员System。out。println(b);mehtod1();静态内部类不能方位外部类的非静态方法method2();}publicstaticvoidmehtod(){System。out。println(hello);}}}publicclassDemo1{publicstaticvoidmain(String〔〕args){Outer。InnerinnewOuter。Inner();通过打印只是执行了静态内部类的构造方法静态内部类是不需要依赖于外部类的在没有外部类的对象的情况下,可以创建静态内部类的对象in。print();in。mehtod();Outer。Inner。mehtod();通过类名点直接调用}}1静态内部类只能直接使用外部类的静态成员2外部类能直接使用内部类的静态成员(静态内部类名。的形式)如果想使用静态内部类的普通方法需要创建静态内部类的对象2。6静态内部类总结1不能使用外部类的非static成员变量或者方法,静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。2属性和方法可以声明为静态的或者非静态的。3实例化静态内部类:比如:B是A的静态内部类,A。BbnewA。B();4内部类只能引用外部类的静态的属性或者方法。5如果属性或者方法声明为静态的,那么可以直接通过类名直接使用。比如B是A的静态内部类,b()是B中的一个静态成员,则可以:A。B。b();6静态内部类不会持有外部类对象引用(外部类的this)