内部类
之前类中可以有变量和方法,今天开始在类中再添加一个元素类。
内部类--包含在类中的类就是内部类
外部类--包含内部类的类就是外部类
1.成员内部类--相当于是java类中的成员变量
基本结构:
public class TestClass {
public class InnerClass{
}
}
TestClass---外部类
InnerClass---成员内部类
内部类编译后会形成一个新的字节码文件【外部类类名$内部类类型.class】
1.成员内部类可以使用任意的访问限制修饰符。
2.成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素。
3.成员内部类中的构造方法可以访问其他的构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法 ,this.实例变量/方法,可以省略对象/this】。
4.成员内部类中的实例方法可以访问构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】。
5.成员内部类中的构造方法可以访问外部类的构造方法,实例方法/变量,类方法/变量。
6.成员内部类中的实例方法可以访问外部类的构造方法,实例方法/变量,类方法/变量。
7.外内部类中的构造方法/实例方法可以访问成员内部类的构造方法,实例方法/变量,外部类中的类方法不能访问成员内部类。
8.其他类中是可以访问成员内部类的,需要依赖外部类对象【先创建外部类对象,再依赖外部类对象来创建成员内部类对象】,注意访问限制修饰符。
例如:
//外部类
public class TestClass {
public String name1="外部类的实例变量";
public static String address="外部类的静态成员变量";
public TestClass(){
System.out.println("外部类的无参构造方法");
InnerClass icl=new InnerClass();
System.out.println(icl.name);
icl.shiLiMethod();
}
public TestClass(int num){
System.out.println("外部类的有参数的构造方法");
InnerClass icl=new InnerClass();
System.out.println(icl.name);
icl.shiLiMethod();
}
public void shiLiMethod1(){
System.out.println("外部类的实例方法");
InnerClass icl=new InnerClass();
System.out.println(icl.name);
icl.shiLiMethod();
}
public static void staticMethod(){
System.out.println("外部类的静态方法");
//静态方法中不能访问内部类中的元素
//InnerClass icl=new InnerClass();
//System.out.println(icl.name);
//icl.shiLiMethod();
}
//成员内部类
//成员内部类不能写静态元素
public class InnerClass{
public String name="内部类的实例变量";
//public static String address="内部类的静态成员变量";
public InnerClass(){
System.out.println("内部类的无参构造方法");
InnerClass ic=new InnerClass(12);
System.out.println(ic.name);
System.out.println(this.name);
System.out.println(name);
ic.shiLiMethod();
this.shiLiMethod();
shiLiMethod();
TestClass tc=new TestClass();
System.out.println(tc.name1);
System.out.println(TestClass.this.name1);
System.out.println(name1);
System.out.println(tc.address);
System.out.println(TestClass.this.address);
System.out.println(TestClass.address);
System.out.println(address);
tc.shiLiMethod1();
TestClass.this.shiLiMethod1();
shiLiMethod1();
tc.staticMethod();
TestClass.this.staticMethod();
TestClass.staticMethod();
staticMethod();
}
public InnerClass(int num){
System.out.println("内部类的有参数构造方法");
InnerClass ic1=new InnerClass();
System.out.println(ic1.name);
System.out.println(this.name);
System.out.println(name);
ic1.shiLiMethod();
this.shiLiMethod();
shiLiMethod();
TestClass tc=new TestClass();
System.out.println(tc.name1);
System.out.println(TestClass.this.name1);
System.out.println(name1);
System.out.println(tc.address);
System.out.println(TestClass.this.address);
System.out.println(TestClass.address);
System.out.println(address);
tc.shiLiMethod1();
TestClass.this.shiLiMethod1();
shiLiMethod1();
tc.staticMethod();
TestClass.this.staticMethod();
TestClass.staticMethod();
staticMethod();
}
public void shiLiMethod(){
System.out.println("内部类的实例方法");
InnerClass ic=new InnerClass(12);
System.out.println(ic.name);
System.out.println(this.name);
System.out.println(name);
ic.shiLiMethod();
this.shiLiMethod();
shiLiMethod();
TestClass tc=new TestClass();
System.out.println(tc.name1);
System.out.println(TestClass.this.name1);
System.out.println(name1);
System.out.println(tc.address);
System.out.println(TestClass.this.address);
System.out.println(TestClass.address);
System.out.println(address);
tc.shiLiMethod1();
TestClass.this.shiLiMethod1();
shiLiMethod1();
tc.staticMethod();
TestClass.this.staticMethod();
TestClass.staticMethod();
staticMethod();
}
/*
public static void staticMethod(){
System.out.println("内部类的静态方法");
}
*/
}
}
其它类中访问成员内部类:
package com.wangxing.chengyuanneibuleidemo;
public class OtherClass {
public OtherClass(){
TestClass tc=new TestClass();
TestClass.InnerClass icl=tc.new InnerClass();
//TestClass.InnerClass icl=new TestClass().new InnerClass();
System.out.println(icl.name);
icl.shiLiMethod();
}
public void shiLi(){
TestClass.InnerClass icl=new TestClass().new InnerClass();
System.out.println(icl.name);
icl.shiLiMethod();
}
public static void staticMethod(){
TestClass.InnerClass icl=new TestClass().new InnerClass();
System.out.println(icl.name);
icl.shiLiMethod();
}
}
2.方法内部类--定义在方法中的类,相当于局部变量
基本格式:
package com.wangxing.test2;
public class TestClass {
public TestClass(){
class InnerClass1{
}
}
public void testMethod(String canshu){
class InnerClass2{
}
}
public static void testStaticMethod(String canshu){
class InnerClass3{
}
}
}
1.方法内部类不能使用任何访问限制修饰符修饰
2.方法内部类中可以有实例变量/方法,构造方法,不能有静态元素
3.方法内部类中的构造方法可以访问本方法内部类中的构造方法,实例方法/变量【对象/this,也可以省略】
4.方法内部类中的实例方法可以访问本方法内部类中的构造方法,实例方法/变量【对象/this,也可以省略】
5.方法内部类中的构造方法/实例方法可以访问本方法的局部变量,默认被访问的局部变量被final修饰【直接变量名称】
6.方法内部类可以访问构造方法,实例方法/变量,静态方法/变量
7.外部类是不能访问到方法内部类的
例如:
package com.wangxing.fangfaneibulei;
import com.sun.org.apache.bcel.internal.classfile.InnerClass;
public class TestClass {
public String name="zhangsan";
public static String staticname="staticzhangsan";
public TestClass(){
// InnerClass ic1=new InnerClass();
}
public void shiliMethod(){}
public static void staticfangfa(){}
public void testMethod(){
String jubu="局部变量";
class InnerClass{
public String a="方法内部类中的实例变量";
//public static String a1="方法内部类中的静态变量";//方法内部类不能写静态变量
public InnerClass(){
System.out.println("方法内部类中的构造方法");
InnerClass ic=new InnerClass();
System.out.println(ic.a);
System.out.println(this.a);
System.out.println(a);
ic.shiLi();
this.shiLi();
shiLi();
// jubu=inner;
System.out.println(jubu);
TestClass tc=new TestClass();
System.out.println(tc.name);
System.out.println(TestClass.this.name);
System.out.println(name);
System.out.println(tc.staticname);
System.out.println(TestClass.this.staticname);
System.out.println(TestClass.staticname);
System.out.println(staticname);
tc.shiliMethod();
TestClass.this.shiliMethod();
shiliMethod();
tc.staticfangfa();
TestClass.this.staticfangfa();
TestClass.staticfangfa();
staticfangfa();
}
public void shiLi(){
System.out.println("方法内部类中的实例方法");
InnerClass ic=new InnerClass();
System.out.println(ic.a);
System.out.println(this.a);
System.out.println(a);
ic.shiLi();
this.shiLi();
shiLi();
TestClass tc=new TestClass();
System.out.println(tc.name);
System.out.println(TestClass.this.name);
System.out.println(name);
System.out.println(tc.staticname);
System.out.println(TestClass.this.staticname);
System.out.println(TestClass.staticname);
System.out.println(staticname);
tc.shiliMethod();
TestClass.this.shiliMethod();
shiliMethod();
tc.staticfangfa();
TestClass.this.staticfangfa();
TestClass.staticfangfa();
staticfangfa();
}
// public static void staticMethod(){}//方法内部类中不能有静态元素
}
}
}
3.静态镶嵌类---相当于是Java类中的静态变量
基本格式:
package com.wangxing.test3;
public class TestClass {
public static class InnerClass{
}
}
1.静态嵌套类中可以有构造方法,实例方法/变量,静态方法/变量
2.静态嵌套类中的构造方法/实例方法可以访问本静态嵌套中的构造方法,实例方法/变量,静态方法/变量
3.静态嵌套类中的静态方法可以访问本静态嵌套类中的构造方法,实例变量/方法【只能对象访问】,静态变量/方法
4.静态嵌套类中的方法可以访问外部类中的构造方法,实例变量/方法【只能对象访问】,静态变量/方法【对象/类名访问】
5.静态嵌套类中不能有this.
6.外部类中的方法可以访问静态嵌套类中的构造方法,实例方法/变量【只能对象】,静态变量/方法【对象/类名访问】
7.其他类中可以访问静态嵌套类【new 外部类类名.静态嵌套类名()】。注意访问限制修饰符
例如:
package com.wangxing.staticneibulei;
public class TestClass {
public String name="实例变量";
public static String address="静态成员变量";
public TestClass(){
System.out.println("构造方法");
//外部类调用静态嵌套类中的实例变量/方法必须使用静态嵌套类的对象,静态方法可以使用对象和类名调用,且不可省略
InnerClass icl=new InnerClass();
System.out.println(icl.name1);
// System.out.println(InnerClass.this.name1);
// System.out.println(name1);
System.out.println(icl.address1);
System.out.println(InnerClass.address1);
// System.out.println(address1);
icl.shiLiMethod();
// InnerClass.this.shiLiMethod();
// shiLiMethood();
icl.jingTai();
InnerClass.jingTai();
// jingtai();
}
public void shiLi(){
System.out.println("实例方法");
InnerClass icl=new InnerClass();
System.out.println(icl.name1);
// System.out.println(InnerClass.this.name1);
// System.out.println(name1);
System.out.println(icl.address1);
System.out.println(InnerClass.address1);
// System.out.println(address1);
icl.shiLiMethod();
// InnerClass.this.shiLiMethod();
// shiLiMethood();
icl.jingTai();
InnerClass.jingTai();
// jingtai();
}
public static void staticMethod(){
System.out.println("静态方法");
InnerClass icl=new InnerClass();
System.out.println(icl.name1);
// System.out.println(InnerClass.this.name1);
// System.out.println(name1);
System.out.println(icl.address1);
System.out.println(InnerClass.address1);
// System.out.println(address1);
icl.shiLiMethod();
// InnerClass.this.shiLiMethod();
// shiLiMethood();
icl.jingTai();
InnerClass.jingTai();
// jingtai();
}
public static class InnerClass{
public String name1="静态嵌套类的实例变量";
public static String address1="静态嵌套类的静态变量";
public InnerClass(){
System.out.println("静态嵌套类的构造方法");
InnerClass ic=new InnerClass();
System.out.println(ic.name1);
System.out.println(this.name1);
System.out.println(name1);
System.out.println(ic.address1);
System.out.println(this.address1);
System.out.println(InnerClass.address1);
System.out.println(address1);
ic.shiLiMethod();
this.shiLiMethod();
shiLiMethod();
ic.jingTai();
this.jingTai();
InnerClass.jingTai();
jingTai();
TestClass tc=new TestClass();
System.out.println(tc.name);
// System.out.println(TestClass.this.name);
// System.out.println(name);
System.out.println(tc.address);
System.out.println(TestClass.address);
System.out.println(address);
tc.shiLi();
// shiLi();
tc.staticMethod();
TestClass.staticMethod();
staticMethod();
}
public void shiLiMethod(){
System.out.println("静态嵌套类的实例方法");
InnerClass ic=new InnerClass();
System.out.println(ic.name1);
System.out.println(this.name1);
System.out.println(name1);
System.out.println(ic.address1);
System.out.println(this.address1);
System.out.println(InnerClass.address1);
System.out.println(address1);
ic.shiLiMethod();
this.shiLiMethod();
shiLiMethod();
ic.jingTai();
this.jingTai();
InnerClass.jingTai();
jingTai();
// 静态嵌套类中的方法调用外部类中的实例变量/方法时必须使用外部类对象进行调用,静态方法可以使用类名,对象进行调用,且可以省略不写
TestClass tc=new TestClass();
System.out.println(tc.name);
// System.out.println(TestClass.this.name);
// System.out.println(name);
System.out.println(tc.address);
System.out.println(TestClass.address);
System.out.println(address);
tc.shiLi();
// shiLi();
tc.staticMethod();
TestClass.staticMethod();
staticMethod();
}
public static void jingTai(){
System.out.println("静态嵌套类的静态方法");
//静态嵌套类中的静态方法调用实例变量/方法时必须使用对象进行调用,调用静态方法时可以使用对象、类名进行调用,也可以省略,其中this不能出现
InnerClass ic=new InnerClass();
System.out.println(ic.name1);
System.out.println(ic.address1);
System.out.println(InnerClass.address1);
System.out.println(address1);
ic.shiLiMethod();
ic.jingTai();
InnerClass.jingTai();
jingTai();
TestClass tc=new TestClass();
System.out.println(tc.name);
// System.out.println(TestClass.this.name);
// System.out.println(name);
System.out.println(tc.address);
System.out.println(TestClass.address);
System.out.println(address);
tc.shiLi();
// shiLi();
tc.staticMethod();
TestClass.staticMethod();
staticMethod();
}
public static void jingTaiMethod(){
InnerClass ic=new InnerClass();
System.out.println(ic.name1);
System.out.println(ic.address1);
System.out.println(InnerClass.address1);
System.out.println(address1);
ic.shiLiMethod();
ic.jingTai();
InnerClass.jingTai();
jingTai();
}
}
}
其他类访问静态嵌套类:
package com.wangxing.staticneibulei;
public class OtherClass {
public OtherClass(){
//在其他类中调用静态嵌套类,必须使用外部类调用静态嵌套类来创建对象
TestClass.InnerClass ic=new TestClass.InnerClass();
//在其他类中调用静态嵌套类中的实例变量/方法必须使用对象调用,调用静态方法使用对象和类名调用,且不可以省略
System.out.println(ic.name1);
// System.out.println(TestClass.InnerClass.this.name1);
// System.out.println(name1);
System.out.println(ic.address1);
System.out.println(TestClass.InnerClass.address1);
// System.out.println(address);
ic.shiLiMethod();
// TestClass.InnerClass.this.shiLiMethod();
// shiLiMethod();
ic.jingTai();
TestClass.InnerClass.jingTai();
// jingTai();
}
public void shiLiFangFa(){
//在其他类中调用静态嵌套类,必须使用外部类调用静态嵌套类来创建对象
TestClass.InnerClass ic=new TestClass.InnerClass();
//在其他类中调用静态嵌套类中的实例变量/方法必须使用对象调用,调用静态方法使用对象和类名调用,且不可以省略
System.out.println(ic.name1);
// System.out.println(TestClass.InnerClass.this.name1);
// System.out.println(name1);
System.out.println(ic.address1);
System.out.println(TestClass.InnerClass.address1);
// System.out.println(address);
ic.shiLiMethod();
// TestClass.InnerClass.this.shiLiMethod();
// shiLiMethod();
ic.jingTai();
TestClass.InnerClass.jingTai();
// jingTai();
}
public static void staticFangFa(){
//在其他类中调用静态嵌套类,必须使用外部类调用静态嵌套类来创建对象
TestClass.InnerClass ic=new TestClass.InnerClass();
//在其他类中调用静态嵌套类中的实例变量/方法必须使用对象调用,调用静态方法使用对象和类名调用,且不可以省略
System.out.println(ic.name1);
// System.out.println(TestClass.InnerClass.this.name1);
// System.out.println(name1);
System.out.println(ic.address1);
System.out.println(TestClass.InnerClass.address1);
// System.out.println(address);
ic.shiLiMethod();
// TestClass.InnerClass.this.shiLiMethod();
// shiLiMethod();
ic.jingTai();
TestClass.InnerClass.jingTai();
// jingTai();
}
}
4.匿名内部类---没有名字的java类,在不用创建出新类的情况下,构建出当前类的子类,构建的子类没有名字,所以叫匿名内部类
基本格式:
package com.wangxing.test4;
public class Person {
public void personInfo(){
System.out.println("Person类的实例方法");
}
}
package com.wangxing.test4;
public class Main {
public static void main(String[] args) {
Person per=new Person(){
public void personInfo(){
System.out.println("重写Person类的personInfo方法");
}
};
per.personInfo();
}
}
new Person(){
public void personInfo(){
System.out.println("重写Person类的personInfo方法");
}
}
上面的代码就是一个匿名内部类的格式,就相当于Person类的子类,只是没有名字,所以叫匿名内部类。
继承式的匿名内部类
例如:
package com.wangxing.nimingneibulei;
public class DemoClass {
public void shiLiMethod(){
System.out.println("实例方法");
}
public void shiLiMethod(TestClass TestClass){
System.out.println("参数类型为TestClass的实例方法");
}
public void shisLiMethod(MyInterface myInterface){
System.out.println("参数类型为MyInterface的实例方法");
}
}
package com.wangxing.nimingneibulei;
public abstract class TestClass {
public abstract void abstractMethod();
}
package com.wangxing.nimingneibulei;
public interface MyInterface {
void chouXiang();
}
package com.wangxing.nimingneibulei;
public class TestMain {
public static void main(String[] args) {
DemoClass dc=new DemoClass(){
public void shiLiMethod(){
System.out.println("重写DemoClass的实例方法");
}
};
dc.shiLiMethod();
/*
DemoClass dc=new DemoClass();
dc.shiLiMethod(new TestClass() {
@Override
public void abstractMethod() {
System.out.println("重写抽象类的抽象方法");
}
});
dc.shisLiMethod(new MyInterface() {
@Override
public void chouXiang() {
System.out.println("重写接口的抽象方法");
}
});
*/
}
}
优点:避免创建额外的独立子类
缺点:不易理解,不易阅读
总结:
内部类:
1.成员内部类---成员变量【实例变量】
2.方法内部类---局部变量
3.静态嵌套类---静态成员变量
4.匿名内部类---创建子类