java学习笔记之——内部类



分类

内部类分为四种:成员内部类,局部内部类,静态内部类,匿名内部类

这四种内部类划分可以分为:

第一种划分:

非静态                                              静态
成员内部类
局部内部类                                   静态内部类
匿名内部类

第二种划分:
成员                                                  局部
成员内部类                                  局部内部类
静态内部类                                  匿名内部类

1、静态的内部类可以含有静态的变量和方法,而非静态的内部类不能含有静态的变量和方法,所以也不能含有静态内部类。

2、内部类可以被public,private,protected等修饰符修饰,但是局部内部类不能被修饰符和static修饰,静态内部类不能被private修饰

3、非静态内部类对象隐式的保存了一个引用,指向一个创建它的外围类对象,静态内部类却没有。

4、当外部类的方法的形参需要被局部的内部类里面使用时,该形参必须为final。

5、如果一个类包含一个内部类编译后会出现两个文件:

外部类.class 和 外部类$内部类.class

6、内部类中的成员变量/方法,局部变量和外部类成员变量/方法重名时,在内部类方法里面

  • 直接通过变量名引用的是,局部变量
  • this.变量名 则引用的是内部类里面的变量
  • outer.this.变量名 引用的是外部类的变量

    静态内部类:

    1、被static修饰的内部类

    2、不能声明为private

    3、静态内部类中可以含有static的成员变量和方法

    4、因为外部类和内部类是一个整体,可以直接new出内部类Outer.inner

    5、因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

    成员内部类:

    1、成员内部类就像是外部类的一个成员,它可以直接访问内部类的所有成员变量和方法,包括private和static修饰的成员。而外部类要访问内部类的成员变量和方法就要通过创建内部类对象。

    2、成员内部类不能含有static的变量和方法

    3、在成员内部类引用外部类的对象时,可以用outer.this引用其对象

    4、在外部类中创建内部类对象 :
    第一种方法:外部类名.内部类名 inner=外部类对象的引用.new 内部类名(参数列表)
    第二种方法:通过方法返回内部类对象

    5、外部类可以创建private内部类,和构造方法为private的普通内部类对象。
    静态内部类和成员内部类代码演示:

    interface Destination{
    	void readLabel();
    }
    interface Contents{
    	void value();
    }
    public class Parcel4 {
    	private String name="Parcel4.this.name: Parcel4";
    	private int i=11;
    	private static String str="静态内部类访问外部类静态变量";
    	
    	private class PContents implements Contents{
    		String name="this.name: PContents";
    		public void value(){
    			String name="name:  PContents inner";
    			System.out.println(name);//内部类方法里的变量
    			System.out.println(this.name);//内部类的成员变量
    			System.out.println(Parcel4.this.name);//外部类的变量
    			System.out.println("i= "+i);//内部类可以访问外部类的private变量
    			}
    	}
    	
    	 static class PDestination implements Destination{
    		 private String label;
    		 private PDestination(String whereTo){
    			label=whereTo;
    		}
    		public void readLabel(){ 
    			System.out.println(label);
    			System.out.println(str);
    			//System.out.println(i);静态内部类不能访问外部类的非静态变量
    			}
    	}
    	 
    	public Contents contents(){
    		return new PContents();
    	}
    	
    	public static void main(String[] args) {
    		Parcel4 p=new Parcel4();
    		Parcel4.PContents pc=p.new PContents();//在外部类new出private成员内部类对象
    		pc.value();
    		Contents pc2=p.contents();//在外部类通过方法返回内部类对象
    		pc2.value();
    		//创建静态内部类对象
    		Parcel4.PDestination pd=new Parcel4.PDestination("静态内部类构造器");
    		pd.readLabel();	
    	}
    }
    
    

    运行结果:
    name: PContents inner
    this.name: PContents
    Parcel4.this.name: Parcel4
    i= 11
    name: PContents inner
    this.name: PContents
    Parcel4.this.name: Parcel4
    i= 11
    静态内部类构造器
    静态内部类访问外部类静态变量

     

     局部内部类:

    1、定义在方法和作用域内部的类,只能在方法区和作用域内部有用。

    2、局部内部类就像是方法里面的局部变量一样,不能有public,protected,private,和static修饰

    3、当内部类要使用外部类的方法形参时,要用到的形参必须是final。

    匿名内部类:

    1、匿名内部类不加访问修饰符和static

    2、不加class和implement

    3、当外部类的方法的形参需要被内部类里面使用时,该形参必须为final

    4、匿名类没有类名,匿名类不能有构造函数。

    5、可以是类也可以是接口

    6、创建:

    new 父类构造器(参数列表)/实现接口(){

    父类构造器和接口不能兼得;

    匿名内部类类体;

    }

    匿名内部类直接用new来生成一个对象的引用,但是这个引用是隐式的。

    7、匿名内部类必须要继承一个父类或者实现一个接口,但是匿名内部类不能是abstract类所以匿名内部类必须要实现父类或者接口中的抽象方法。

    8、匿名内部类是局部内部类,所以受局部内部类的限制。同时也是非静态内部类,所以不能含有静态变量和方法。

    9、匿名内部类不可能有命名构造器,但是通过实例初始化,就能,就能达到为匿名类创建一个构造器的效果。
    匿名内部类代码演示:

    interface Destination{
    	String readLabel();
    }
    public class Parcel10 {
    	public Destination destintion(final String dest,final float price){
    		//dest,和price在类的内部被用到
    		return new Destination(){//匿名内部类实现Destination接口
    			private int cost;
    			{//匿名内部类的实例初始化
    				cost=Math.round(price);//将双精度数舍入为最接近的整数
    				if(cost>100)
    					System.out.println("Over budget!");
    			}
    			private String label=dest;
    			public String readLabel(){return label;}
    		};//匿名内部类类体结束
    	}
    	public static void main(String[] args) {
    		Parcel10 p=new Parcel10();
    		Destination d=p.destintion("Tasmania", 101.395f);
    	}
    }
    
    

    运行结果:
    Over budget!
    局部内部类与匿名内部类代码演示:

    interface Counter{
    	int next();
    }
    public class LocalInnerClass {
    	private int count=0;
    	Counter getCounter(final String name){//局部内部类要用到name
    	     //局部内部类
    		class LocalCounter implements Counter{
    			public LocalCounter(){
    				System.out.println("LocalCounter()");//局部内部类构造器
    			}
    			public int next(){
    				System.out.print(name);
    				return count++;
    			}
    		}
    		return new LocalCounter();//局部内部类,只能在方法或者作用域内有用
    }
    	Counter getCounter2(final String name){
    		//匿名内部类
    		return new Counter(){
    			//实现Counter接口的匿名内部类
    			//实例初始化,相当于匿名内部类的构造器
    			{
    				System.out.println("Counter()");
    			}
    			public int next(){
    				System.out.print(name);
    				return count++;
    			}
    		};//匿名内部类类体结束,这里分号不能丢
    	}
    	public static void main(String[] args) {
    		LocalInnerClass lic=new LocalInnerClass();
    		Counter
    		c1=lic.getCounter("Local inner "),
    		c2=lic.getCounter2("Anonymous inner "),
    		c3=lic.getCounter2("Anonymous inner2 ");
    		for(int i=0;i<5;i++)
    			System.out.println(c1.next());
    		for(int i=0;i<5;i++)
    			System.out.println(c2.next());
    		for(int i=0;i<5;i++)
    			System.out.println(c3.next());
    	}
    }
    
    

    运行结果:
    LocalCounter()
    Counter()
    Counter()
    Local inner0
    Local inner1
    Local inner2
    Local inner3
    Local inner4
    Anonymous inner5
    Anonymous inner6
    Anonymous inner7
    Anonymous inner8
    Anonymous inner9
    Anonymous inner2 10
    Anonymous inner2 11
    Anonymous inner2 12
    Anonymous inner2 13
    Anonymous inner2 14

     内部类被继承:

    子类的构造函数要传入外部类的引用,并通过父类的外部类对象.super()去继承父类的构造函数。父类对象要在外面创建并传递给形参。
    代码演示:

    class WithInner{
    	class Inner{}
    }
    public class InheritInner extends WithInner.Inner{
    	InheritInner(WithInner wi){
    		wi.super();
    	}
    	public static void main(String[] args) {
    		WithInner wi=new WithInner();
    		InheritInner ii=new InheritInner(wi);
    	}
    }
    
    




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值