内部类---包含在类中的类
外部类---包含内部类之外的类就是外部类
1.成员内部类---相当于java类中的成员变量
基本结构:
package com.object.test1;
public class TestClass {
public class InClass{}
}
TestClass---外部类
InClass---成员内部类
内部类编译后会形成一个新的字节码文件【外部类类名$内部类类名.class】
1.成员内部类可以使用任意的访问限制修饰符
package com.object.test1; public class TestClass { public class InClass{ //public访问限制修饰符定义的变量 public String name="zhangsan"; //缺省的访问限制修饰符定义的变量 int age=23; //受保护的访问限制修饰符定义的变量 protected String address="西安"; //私有的的访问限制修饰符定义的变量 private int id=1001; } }
2.成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。
package com.object.test1; public class TestClass { public class InClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。 //实例变量 public int id=1001; //成员内部类不能有静态变量 //public static String name="zhangsan"; //报错 //构造方法 public InClass(){ System.out.println("InClass成员内部类构造方法"); } //实例方法 public void testMethod(){ System.out.println("InClass成员内部类实例方法"); } //静态方法 //成员内部类不能有静态方法 //public static staticMethod(){} //报错 } }
3.成员内部类中的构造方法可以访问其他的构造方法【new】,
可以访问实例变量/方法:【对象.实例变量/方法 ,this.实例变量/方法,可以省略对象/this】
package com.object.test1; public class TestClass { public class InClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。 //实例变量 public int id=1001; //成员内部类不能有静态变量 //public static String name="zhangsan"; //报错 //构造方法 //InClass成员内部类无参数构造方法 public InClass(){ System.out.println("InClass成员内部类无参数构造方法"); } //InClass成员内部类有参数构造方法 public InClass(String name){ //成员内部类中的构造方法可以访问其他的构造方法【new】 //可以访问实例变量/方法【对象.实例变量/方法 ,this.实例变量/方法,可以省略对象/this】 new InClass(); //内部类对象 new InClass().id=1002; this.id=1003; id=1004; new InClass().testMethod(); this.testMethod(); testMethod(); System.out.println("InClass成员内部类有参数构造方法"); } //实例方法 //InClass成员内部类testMethod实例方法 public void testMethod(){ } //InClass成员内部类testMethod2实例方法 public void testMethod2(){ } }
4.成员内部类中的实例方法可以访问构造方法【new】
可以访问实例变量/方法:【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】
package com.object.test1; public class TestClass { public class InClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。 //实例变量 public int id=1001; //成员内部类不能有静态变量 //public static String name="zhangsan"; //报错 //构造方法 //InClass成员内部类无参数构造方法 public InClass(){ System.out.println("InClass成员内部类无参数构造方法"); } //InClass成员内部类有参数构造方法 public InClass(String name){ //成员内部类中的构造方法可以访问其他的构造方法【new】 //可以访问实例变量/方法【对象.实例变量/方法 ,this.实例变量/方法,可以省略对象/this】 new InClass(); //内部类对象 new InClass().id=1002; this.id=1003; id=1004; new InClass().testMethod(); this.testMethod(); testMethod(); System.out.println("InClass成员内部类有参数构造方法"); } //实例方法 //InClass成员内部类testMethod实例方法 public void testMethod(){ //成员内部类中的实例方法可以访问构造方法【new】 //可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】 new InClass(); //内部类对象 new InClass().id=1002; this.id=1003; id=1004; new InClass().testMethod2(); this.testMethod2(); testMethod2(); System.out.println("InClass成员内部类testMethod实例方法"); } //InClass成员内部类testMethod2实例方法 public void testMethod2(){ System.out.println("InClass成员内部类testMethod2实例方法"); } }
5.成员内部类中的构造方法/实例方法可以访问外部类的构造方法,实例方法/变量,类方法/变量。
package com.object.test1; public class TestClass { //实例变量 public int age=23; //静态成员变量 public static String name="lisi"; //构造方法 public TestClass(){ System.out.println("TestClass无参数构造方法"); } //实例方法 public void shiliMethod(){ System.out.println("TestClass无参数实例方法"); } //静态方法 public static void staticMethod(){ System.out.println("TestClass无参数实例方法"); } public class InClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。 //实例变量 public int id=1001; //成员内部类不能有静态变量 //public static String name="zhangsan"; //报错 //构造方法 //InClass成员内部类无参数构造方法 public InClass(){ System.out.println("InClass成员内部类无参数构造方法"); } //InClass成员内部类有参数构造方法 public InClass(String name){ //成员内部类中的构造方法可以访问其他的构造方法【new】 new InClass(); //内部类对象 new InClass().id=1002; this.id=1003; id=1004; new InClass().testMethod(); this.testMethod(); testMethod(); //访问外部变量和方法 //成员内部类中的构造方法可以访问实例变量/方法【对象.实例变量/方法 ,this.实例变量/方法,可以省略对象/this】 new TestClass(); //访问外部类实例变量 new TestClass().age=25; TestClass.this.age=27; age=29; //访问外部类静态变量 new TestClass().name="wangwu"; TestClass.this.name="zhaowu"; name="zhubajie"; //访问外部类实例方法 new TestClass().shiliMethod(); TestClass.this.shiliMethod(); shiliMethod(); //访问外部类静态方法 new TestClass().staticMethod(); TestClass.this.staticMethod(); staticMethod(); System.out.println("InClass成员内部类有参数构造方法"); } //实例方法 //InClass成员内部类testMethod实例方法 public void testMethod(){ //成员内部类中的实例方法可以访问构造方法【new】 //可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】 new InClass(); //内部类对象 new InClass().id=1002; this.id=1003; id=1004; new InClass().testMethod2(); this.testMethod2(); testMethod2(); //访问外部变量和方法 //成员内部类中的实例方法可以访问实例变量/方法【对象.实例变量/方法 ,this.实例变量/方法,可以省略对象/this】 new TestClass(); //访问外部类实例变量 new TestClass().age=25; TestClass.this.age=27; age=29; //访问外部类静态变量 new TestClass().name="wangwu"; TestClass.this.name="zhaowu"; name="zhubajie"; //访问外部类实例方法 new TestClass().shiliMethod(); TestClass.this.shiliMethod(); shiliMethod(); //访问外部类静态方法 new TestClass().staticMethod(); TestClass.this.staticMethod(); staticMethod(); System.out.println("InClass成员内部类testMethod实例方法"); } //InClass成员内部类testMethod2实例方法 public void testMethod2(){ System.out.println("InClass成员内部类testMethod2实例方法"); } //静态方法 //成员内部类不能有静态方法 //public static staticMethod(){} //报错 } }
6.外部类中的构造方法/实例法可以访问成员内部类的构造方法,实例方法/变量,外部类中的
类方法不能访问成员内部类。【只能对象访问,不能省略对象,也不可以this访问】
package com.object.test1; public class TestClass { //实例变量 public int age=23; //静态成员变量 public static String name="lisi"; //构造方法 public TestClass(){ //访问内部类中的变量和方法 new InClass(); //内部类对象 new InClass().id=1002; //this.id=1003; //id=1004; new InClass().testMethod(); //this.testMethod(); //testMethod(); System.out.println("TestClass无参数构造方法"); } //实例方法 public void shiliMethod(){ new InClass(); //内部类对象 new InClass().id=1002; //this.id=1003; //id=1004; new InClass().testMethod(); //this.testMethod(); //testMethod(); System.out.println("TestClass无参数实例方法"); } //静态方法 public static void staticMethod(){ //new InClass(); //内部类对象 //new InClass().id=1002; //this.id=1003; //id=1004; //new InClass().testMethod(); //this.testMethod(); //testMethod(); System.out.println("TestClass无参数实例方法"); } public class InClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。 //实例变量 public int id=1001; //成员内部类不能有静态变量 //public static String name="zhangsan"; //报错 //构造方法 //InClass成员内部类无参数构造方法 public InClass(){ System.out.println("InClass成员内部类无参数构造方法"); } //InClass成员内部类有参数构造方法 public InClass(String name){ } //实例方法 //InClass成员内部类testMethod实例方法 public void testMethod(){ ; System.out.println("InClass成员内部类testMethod实例方法"); } //InClass成员内部类testMethod2实例方法 public void testMethod2(){ System.out.println("InClass成员内部类testMethod2实例方法"); } } }
7.其他类中是可以访问成员内部类的,需要依赖外部类对象,注意访问限制修饰符。
package com.object.test1; public class OtherClass { //构造方法 public OtherClass(){ TestClass tcl=new TestClass(); TestClass.InClass inc1=tcl.new InClass(); TestClass.InClass inc2=new TestClass().new InClass(); inc1.id=1004; inc2.id=1005; inc1.testMethod(); inc2.testMethod(); } //实例方法 public void shiliOtherClass(){ TestClass tcl=new TestClass(); TestClass.InClass inc1=tcl.new InClass(); TestClass.InClass inc2=new TestClass().new InClass(); inc1.id=1004; inc2.id=1005; inc1.testMethod(); inc2.testMethod(); } //静态方法 public static void staticOtherClass(){ TestClass tcl=new TestClass(); TestClass.InClass inc1=tcl.new InClass(); TestClass.InClass inc2=new TestClass().new InClass(); inc1.id=1004; inc2.id=1005; inc1.testMethod(); inc2.testMethod(); } }
2.方法内部类--定义在方法中的类,相当于局部变量
1.基本格式:
package com.object.test2; public class TestClass { //构造方法中的方法内部类 public TestClass(){ class InTestClass1{ } } //实例方法中的方法内部类 public void testMethod(){ class InTestClass2{ } } //静态方法中的方法内部类 public static void staticMethod(){ class InTestClass3{ } } }
1.方法内部类不能使用任何访问限制修饰符。
2.方法内部类可以有实例变量/方法,构造方法,不能有静态元素。
3.方法内部类的构造方法/实例方法可以访问本方法内部类中的构造方法,实例方法/变量【对象/this,也可以省略】。
4.方法内部类中的构造方法/实例方法中可以访问本方法的局部变量,默认会使用final修饰局部变量【直接变量名称】。
5.方法内部类可以访问外部类的构造方法,实例方法/变量,类方法/变量。
6.外部类不能访问方法内部类。
package com.object.test2; public class TestClass { //方法内部类可以访问外部类的构造方法,实例方法/变量,类方法/变量。 //实例变量 public int num=23; //静态成员变量 public String nam="wangwu"; //构造方法 public TestClass(){} //实例方法 public void testshiliClass(){} //静态方法 public static void staticMethod(){} //实例方法中的方法内部类 public void testMethod(){ class InTestClass2{ //方法内部类可以有实例变量 public int id=1001; //方法内部类不能有静态元素 //public static String name="zhangsan"; //方法内部类可以有实例方法,构造方法, public InTestClass2(){} public InTestClass2(int age){ //方法内部类的构造方法中可以访问本方法内部类中的构造方法 new InTestClass2(); //方法内部类的构造方法中可以访问本方法内部类中实例方法/变量【对象/this,也可以省略】 new InTestClass2().shiliMethod1(); this.shiliMethod1(); shiliMethod1(); new InTestClass2().id=1002; //方法内部类可以访问外部类的构造方法,实例方法/变量,类方法/变量。 new TestClass(); new TestClass().nam="lilu"; TestClass.this.nam="wangwu"; nam="liuqian"; new TestClass().num=27; TestClass.this.num=32; num=30; new TestClass().staticMethod(); TestClass.this.staticMethod(); staticMethod(); new TestClass(). testshiliClass(); TestClass.this.testshiliClass(); testshiliClass(); } public void shiliMethod1(){} public void shiliMethod2(){ //方法内部类的构造方法中可以访问本方法内部类中的构造方法 new InTestClass2(); //方法内部类的构造方法中可以访问本方法内部类中实例方法/变量【对象/this,也可以省略】 new InTestClass2().shiliMethod1(); this.shiliMethod1(); shiliMethod1(); new InTestClass2().id=1002; new TestClass(); new TestClass().nam="lilulu"; new TestClass().num=29; new TestClass().staticMethod(); new TestClass(). testshiliClass(); //方法内部类不能有静态方法 //public static void Instatic(){} } } } }
3.静态嵌套类--相当于是java类中的静态变量
基本格式:
package com.object.test3; public class TestClass { //静态嵌套类 public static class InClass{ } }
1.静态嵌套类中可以有构造方法,实例变量/方法,类变量/方法。
2.静态嵌套类中构造方法/实例方法可以访问本静态嵌套类中的构造方法,实例变量/方法,类变量/方法。
3.静态内部类中类方法可以访问本静态嵌套类中的构造方法,实例变量/方法【只能对象】,类变量/方法.
4.静态内部类中的构造方法/实例方法/类方法可以访问外部类的构造方法,实例变量/方法【只能对象】,类变量/方法。
5.静态嵌套类中不能有this.
6.外部类的构造方法/实例方法/类方法可以访问,静态内部类中构造方法,实例变量/方法【只能对象】,类变量/方法.
7.其他类中可以访问静态嵌套类【new 外部类类名.静态嵌套类名()】。注意访问限制修饰符
package com.object.test3; public class TestClass { //实例变量 public String nam="zhangsan"; //静态成员变量 public static int num=112; //构造方法 public TestClass(){ new InClass(); new InClass().id=1002; //this.id=1003; //id=1004; new InClass().age=25; // this.age=26; //age=28; new InClass().shiliMethod1(); //this.shiliMethod1(); //shiliMethod1(); new InClass().staticMethod(); InClass.staticMethod(); // this.staticMethod(); //staticMethod(); } //实例方法 public void testClassMethod(){ new InClass(); new InClass().id=1002; //this.id=1003; //id=1004; new InClass().age=25; // this.age=26; //age=28; new InClass().shiliMethod1(); //this.shiliMethod1(); //shiliMethod1(); new InClass().staticMethod(); InClass.staticMethod(); // this.staticMethod(); //staticMethod(); } //静态方法 public static void testClassStatic(){ new InClass(); new InClass().id=1002; //this.id=1003; //id=1004; new InClass().age=25; // this.age=26; //age=28; new InClass().shiliMethod1(); //this.shiliMethod1(); //shiliMethod1(); new InClass().staticMethod(); InClass.staticMethod(); // this.staticMethod(); //staticMethod(); } //静态嵌套类 public static class InClass{ //静态嵌套类中可以有构造方法,实例变量/方法,类变量/方法。 public int age=23; public static int id=1001; public InClass(){} public InClass(String name){ //静态嵌套类中构造方法可以访问本静态嵌套类中的构造方法,实例变量/方法,类变量/方法。 new InClass(); new InClass().id=1002; this.id=1003; id=1004; new InClass().age=25; this.age=26; age=28; new InClass().shiliMethod1(); this.shiliMethod1(); shiliMethod1(); new InClass().staticMethod(); this.staticMethod(); staticMethod(); new TestClass(); new TestClass().nam="wahaha"; //this.nam="zhaoxi";//报错 //nam="zhaoliu"; //TestClas.this.nam="zhaoxi";//报错 new TestClass().num=234; TestClass.num=244; //this.num=245;//报错 //TestClass.this.num=247;//报错 num=211; new TestClass().testClassMethod(); //TestClass.this.testClassMethod(); //testClassMethod(); new TestClass().testClassStatic(); TestClass.testClassStatic(); //TestClass.this.testClassStatic(); //this.testClassStatic(); testClassStatic(); } //实例方法 public void shiliMethod1(){} public void shiliMethod2(){ //静态嵌套类中实例方法可以访问本静态嵌套类中的构造方法,实例变量/方法,类变量/方法。 new InClass(); new InClass().id=1002; this.id=1003; id=1004; new InClass().age=25; this.age=26; age=28; new InClass().shiliMethod1(); this.shiliMethod1(); shiliMethod1(); new InClass().staticMethod(); this.staticMethod(); staticMethod(); new TestClass(); new TestClass().nam="wahaha"; //this.nam="zhaoxi";//报错 //nam="zhaoliu"; //TestClas.this.nam="zhaoxi";//报错 new TestClass().num=234; TestClass.num=244; //this.num=245;//报错 //TestClass.this.num=247;//报错 num=211; new TestClass().testClassMethod(); //TestClass.this.testClassMethod(); //testClassMethod(); new TestClass().testClassStatic(); TestClass.testClassStatic(); //TestClass.this.testClassStatic(); //this.testClassStatic(); testClassStatic(); } //静态方法 public static void staticMethod(){} public static void staticMethod2(){ //静态内部类中类方法可以访问本静态嵌套类中的构造方法,实例变量/方法【只能对象】,类变量/方法. new InClass(); new InClass().id=1002; //this.id=1003; id=1004; new InClass().age=25; //this.age=26; //age=28; new InClass().shiliMethod1(); //this.shiliMethod1(); //shiliMethod1(); new InClass().staticMethod(); //this.staticMethod(); staticMethod(); new TestClass(); new TestClass().nam="wahaha"; //this.nam="zhaoxi";//报错 //nam="zhaoliu"; //TestClas.this.nam="zhaoxi";//报错 new TestClass().num=234; TestClass.num=244; //this.num=245;//报错 //TestClass.this.num=247;//报错 num=211; new TestClass().testClassMethod(); //TestClass.this.testClassMethod(); //testClassMethod(); new TestClass().testClassStatic(); TestClass.testClassStatic(); //TestClass.this.testClassStatic(); //this.testClassStatic(); testClassStatic(); } } }
package com.object.test3; public class OtherClass { public void otherMethod(){ //其他类中可以访问静态嵌套类【new 外部类类名.静态嵌套类名()】。注意访问限制修饰符 TestClass. InClass into =new TestClass. InClass(); new TestClass. InClass().age=12; into.id=1005; into.shiliMethod1(); into.staticMethod(); } }
4.匿名内部类
1.没有名字的java类,再不用创建新类的情况下,构建出当前类的子类,构建的子类
没有名称,所以叫匿名内部类
2.基本格式:
package com.object.test4; public class Person { public void personIn(){ System.out.println("Person类的实例方法"); } }
package com.object.test4; public class TestMain { public static void main(String[] args) { Person per=new Person(){ public void personIn(){ System.out.println("重写Person类的实例方法"); } }; per.personIn(); } }
new Person(){ public void personIn(){ System.out.println("重写Person类的实例方法"); } };上面的代码就是一个匿名内部类的格式,就相当于Person类的子类,只是没有名字,所以叫匿名内部类。
3.继承式的匿名内部类
例如:
package com.wangxing.test5; public abstract class Person { public abstract void perinfo(); }
package com.wangxing.test5; public class TestClass { public void testClassShili(Person person){ person.perinfo(); } }
package com.object.test5; public class TestMain { public static void main(String[] args) { TestClass tcl=new TestClass(); tcl.testClassMethod(new Person(){ @Override public void personIn() { System.out.println("重写后的抽象类方法"); } }); } }
4.接口式的匿名内部类
例如:
package com.object.test6; public interface Person { void interfaceperson(); }
package com.object.test6; public class TestClass { public void testClassMethod(Person person){ person.interfaceperson(); } }
package com.object.test6; public class TestMain { public static void main(String[] args) { //当一个方法的参数是接口类型的时候,可以传递接口回调对象/当前接口的子类 //无论是接口回调对象/当前接口的子类,都要创建子类 //匿名内部类,可以在不需要创建子类的情况下,完成参数传递 TestClass tcl=new TestClass(); tcl.testClassMethod(new Person(){ @Override public void interfaceperson() { System.out.println("重写后的抽象类方法"); } }); } }
优点:避免创建额外的独立子类。
缺点:不易理解,不易阅读。