2020年9月1日 类的成员、静态成员内部类(静态内部类)、非静态的成员内部类
* 类的成员:
* 1、属性:成员变量
* 2、方法:成员方法
* 3、构造器
* 4、代码块
* 5、内部类:成员内部类
*
* 其中1、2是代表这类事物的特征
* 其中3、4是初始化类和对象用的
* 其中5协助完成2的功能的实现,表现
*
* 什么情况下会用到成员内部类(方法外声明的)?
* 当描述一个事物时,发现它的内部还有一个完整的结构需要用一个类来描述;
* 并且发现这内部的结构,如果独立存在是没有意义的,必须在这个外部类中才有意义。而且这个内部结构只为这个外部类服务。
*
* 例如:Body身体,发现它内部还有完整的结构,例如:心脏
* 发现心脏单独创建对象没有意义,只有在Body对象中才有意义,而且只为Body对象服务。
* 成员内部类分为两种: * 1、静态成员内部类,简称静态内部类 * 【修饰符】 class 外部类{ * 【其他修饰符】 static class 内部类{ * } * } * 【修饰符】 class 外部类 【 extends 父类】 【implements 父接口们】{ * 【其他修饰符】 static class 内部类 【 extends 父类】 【implements 父接口们】{ * } * } * 注意:只有成员内部类才能用static修饰,其他的外部类,局部内部类等都不可以用static修饰 * * 2、非静态成员内部类 * 【修饰符】 class 外部类{ * 【其他修饰符】 class 内部类 { * } * } * 【修饰符】 class 外部类 【 extends 父类】 【implements 父接口们】{ * 【其他修饰符】 class 内部类 【 extends 父类】 【implements 父接口们】{ * } * }
package com.atguigu.test02; //import com.atguigu.test02.Outer.Inner; /* * 二、静态内部类 * * 1、特点 * (1)静态内部类中,可以出现原本类中能够定义的所有的成员 * 属性:可以有静态属性和非静态属性 * 方法:可以有静态方法和非静态方法 * 如果静态内部类是抽象类的话,还可以定义抽象方法 * 构造器:有参、无参 * 代码块:可以有静态代码块和非静态代码块 * 内部类:允许,很少再写内部类(不讨论内部类的内部类) * * (2)静态内部类中不能使用外部类的非静态的成员 * (3)在外部类中,使用静态内部类,和使用其他的类一样的原则 * 如果使用静态内部类的静态成员,直接“静态内部类名.” * 如果使用静态内部类的非静态成员,直接“静态内部类对象名.” * (4)在外部类的外面,使用静态内部类 * 如果使用静态内部类的静态成员,直接“类名.” * 使用外部类名.静态内部类名.静态方法 * 使用import 包.外部类名.静态内部类名; 在代码中使用 “静态内部类名.” * 如果使用静态内部类的非静态成员,“静态内部类对象名.” * * (5)静态内部类不会随着外部类的初始化一起初始化,而是要在使用到这个静态内部类是才会初始化 * * * 2、结论 * (1)同级的来说静态的不能直接使用非静态的 * (2)访问一个类的静态成员,用“类名.”即可, * 访问一个类的非静态成员,用“对象名.”即可, * (3)一个类需要初始化,得用到这个类 */ public class TestStaticInner { public static void main(String[] args) { /*// Inner.test();//上面有导包语句,import 包.外部类名.静态内部类名; Outer.Inner.test();//外部类名.静态内部类名.静态方法 // Inner in = new Inner();//上面有导包语句,import 包.外部类名.静态内部类名; Outer.Inner in = new Outer.Inner(); in.method();*/ Outer out = new Outer(); out.outMethod(); } } class Outer{ private int i = 1; private static int j = 2; static{ System.out.println("外部类的静态代码块"); } static class Inner{ static{ System.out.println("静态内部类的代码块"); } public void method(){ System.out.println("静态内部类的非静态方法"); // System.out.println(i);//错误 System.out.println(j); } public static void test(){ System.out.println("静态内部类的静态方法"); } } public void outMethod(){ Inner in = new Inner(); in.method();//非静态方法,用对象名.访问 Inner.test();//静态方法,用类名.访问 } }
package com.atguigu.test03; /* * 三、非静态的成员内部类 * * 1、特点: * (1)在非静态内部类中,不能出现任何和static有关的声明 * (2)在非静态内部类中,可以随意访问外部类的所有的成员,包括静态的和非静态的 * (3)在外部类的静态成员中,不能使用非静态的成员内部类 * (4)在外部类的外面使用 * 第一步:先创建外部类的对象 * 第二步:要么通过外部类的对象,去创建内部类的对象 * Outer out = new Outer(); Outer.Inner in = out.new Inner(); * 要么通过外部类的对象,去获取内内部类的对象 * Outer out = new Outer(); * Outer.Inner in = out.getInner(); * * */ public class TestNonStaticInner { public static void main(String[] args) { // Outer.Inner in = new Outer.Inner();//错误的 //我们要在这里使用Inner,因为此时的Inner是Outer的非静态成员,所以需要用到Outer的对象 Outer out = new Outer(); // Outer.Inner in = out.new Inner(); Outer.Inner in = out.getInner(); in.method(); } } class Outer{ private int i = 1; private static int j = 2; class Inner{ public void method(){ System.out.println("非静态内部类的非静态方法"); System.out.println(i); System.out.println(j); } } public static void outTest(){ // Inner in = new Inner();//静态的方法不能访问非静态的成员 } public void outMethod(){ Inner in = new Inner(); in.method(); } public Inner getInner(){ return new Inner(); } }
package com.atguigu.test04; import com.atguigu.test04.Outer.Inner; public class TestExer { public static void main(String[] args) { MySub my = new MySub(new Outer()); my.test(); } } class Outer{ abstract class Inner{ public abstract void test(); } } //class MySub 去继承Inner,重写test()打印"hello",并在测试中调用 /* * (1)使用非静态内部类名时,可以使用 * import 包.外部类名.内部类名; * (2)要调用非静态内部类的构造器,需要用到外部类的对象 * (3)因为子类的构造器的首行一定要调用父类的构造器,默认调用父类的无参构造 * (4)继承抽象类,要重写抽象的抽象方法 */ class MySub extends Inner{ MySub(Outer out){ out.super();//需要外部类的对象,才能调用非静态内部类的构造器 } @Override public void test() { System.out.println("hello"); } }