java内部类

内部类

定义在另外一个类中的类,内部类是个编译时的概念,一旦编译成功后,它就与外围类属于两个完全不同的类(内部类获取有外围类的引用),对于一个名为OuterClass的外围类和一个名为InnerClass的内部类,在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$InnerClass.class。

作用:

1.内部类可以隐藏在外部类之内,不允许其他类直接访问,封装性更好。

2.内部类可以直接访问外部类的所有数据,包括私有数据。内部类使用起来更灵活

分类:

1.成员内部类

1.1 外部类要访问内部类要先实例化外部类,通过实例.new 内部类()产生内部类实例访问内部类数据,内部类和外部类可以有相同的变量和方法,优先访问自己的,内部类在实例化的时候获得外部类的引用,可使用外部类名.this访问外部类。

1.2 成员内部类可以无条件地访问外部类的成员,编译器会默认为成员内部类添加了一个指向外部类对象的引用.

1.3如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问

1.4 成员内部类中不能存在任何static的变量和方法


引用网上简单示例:

public class OuterClass {
    private String str;
    
    public void outerDisplay(){
        System.out.println("outerClass...");
    }
    
    public class InnerClass{
        public void innerDisplay(){
            //使用外围内的属性
            str = "chenssy...";
            System.out.println(str);
            //使用外围内的方法
            outerDisplay();
        }
    }
    /*推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 */
    public InnerClass getInnerClass(){
        return new InnerClass();
    }
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.getInnerClass();
        inner.innerDisplay();
    }
}
chenssy...
outerClass...

创建成员内部类对象的一般形式为:  外部类类名.内部类类名 xxx = 外部类对象名.new 内部类类名()

2.静态内部类

static修饰的内部类,独立于外部类,可以在不创建外部类对象的情况下创建内部类的对象。静态内部类不持有指向外部类对象的引用,不能直接访问外部类的非静态成员,对于外部类的静态变量(不同名)可以直接使用变量名访问,同名的话使用类名.静态名访问

public class testmemberinnerclass {
	private final int a;//空final
	private  static int b;//类加载时会赋初值给类变量
	private static final int c;//final修饰的不会初始赋值
	static {
		c=0;
	}
	public testmemberinnerclass(int j,int l){
		a=j;
		System.out.println("构造a:"+a);
		b=l;
		System.out.println("构造b:"+b);
	}
	private class innerclass {
		void m2_inner(int i, int k) {
			b = k;
			System.out.println("inner class a:" + a);
			System.out.println("inner class b:" + b);
		}
	}
	static class innerclass2 {
		void m2_inner(int i, int k) {
			b = k;
//			System.out.println("inner class a:" + a);
			testmemberinnerclass test=new testmemberinnerclass(10,11);
			System.out.println("inner class b:" +test.a);
			System.out.println("inner class b:" + b);
		}
	}
        public static void main(){
            testmemberinnerclass outer = new testmemberinnerclass(10,11);
        innerclass inner = outer.new innerclass();// 必须通过包含内部类的外部类去访问内部类
        inner.m2_inner(4, 5);  
               //创建静态内部类的方式

              innerclass2 i2=new testmemberinnerclass.innerclass2();

}
 }

创建静态内部类对象的一般形式为:  外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()

3.方法内部类

局部内部类的访问仅限于方法内或者该作用域内,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

示例

public void m3(){
		class methodinnerclass{
			void print(){
				System.out.println("方法内部类");
			}
		}
		methodinnerclass methodinnerclass=new methodinnerclass();
		methodinnerclass.print();
	}

4.匿名内部类

匿名内部类没有构造器,没有访问修饰符格式 new method(){do};分号不可省略,另外new的时候类一定是要存在的,do重写或实现类的方法

匿名内部类在编译的时候由系统自动起名为Outter$1.class

匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写

局部(方法)内部类和匿名内部类只能访问局部final变量,因为到局部内部类的方法传参是值传递,在内部类的方法修改了参数对元参数无效造成数据不一致,所以就限定内部类方法中的局部变量和形参都必须用final进行限定,当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。

示例

public A m2(final int count,String str){//匿名内部类使用到的变量必须设置成final,str未在匿名内部类使用所以不需要设置成final
		System.out.println("进入m2方法");
		return new A(){
			public void domth() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类"+count);
			}
	};//分号表示匿名内部类的终结,不可少
	}
 interface A{//此接口一定要有,否则匿名内部类出错类
	void domth();
}
public static void main(String args[]) {
		 testmemberinnerclass outer3 = new testmemberinnerclass(10,11);
		 A a=outer3.m2(199,"abc");
		 a.domth();
	}
}

使用内部类作用

1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响,内部类的存在使得Java的多继承机制变得更加完善

2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

3.方便编写事件驱动程序

4.方便编写线程

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值