Java中的内部类详细总结

非静态内部类

 

例1.

//外部类
class Out {
    private int age = 12;
     
    //内部类
    class In {
        public void print() {
            System.out.println(age);    //非静态内部类成员可以访问外部类的private成员</span>
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
        //或者采用下种方式访问
        /*
        Out out = new Out();
        Out.In in = out.new In();
        in.print();
        */
    }
}

运行结果:12

 

程序编译过后会产生两个.class文件,分别是Out.class和Out$In.class

前者是外部类Out的class文件,后者是内部类In的class文件。

即成员内部类(静态内部类和非静态内部类)的class文件总是这种形式:OuterClass$InnerClass.class

 

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

 

Out.In in = new Out().new In()可以用来生成内部类的对象,这种方法存在两个小知识点需要注意

  1.开头的Out是为了标明需要生成的内部类对象在哪个外部类当中

  2.必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量

 

 

 

 

例2.

 

class Out {
    private int age = 12;
     
    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("内部类方法里的局部变量:" + age);
            System.out.println("内部类成员变量:" + this.age);
            System.out.println("外部类成员变量:" + Out.this.age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
    }
}

 

 

 

运行结果:

局部变量:14
内部类变量:13
外部类变量:12

非静态内部类的变量访问形式

在非静态内部类的方法内访问某个变量时,优先在该方法内查找是否存在该名字的局部变量;

若无,到该方法所在的内部类中查找是否存在该名字的成员变量;

若无,到该内部类所在的外部类中查找是否存在该名字的成员变量;

 

if 外部类的成员变量,内部类的成员变量,内部类方法里的局部变量同名:

访问外部类的成员变量                            Out.this.属性名

访问内部类的成员变量                             this.属性名

访问内部类方法里的局部变量                 属性名

 

 

例3.

 

public class Out{

private class In{}

public static void main(String[] args){
new In();  //编译异常
}
}

运行结果:编译异常

 

 

不允许在外部类的静态成员中直接使用非静态内部类。

 

非静态内部类里不能有静态方法,静态成员变量,静态初始化块。
 

 

静态内部类

例4.

 

class Out {
    private static int age = 12;
     
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
}

运行结果:12

 

如果用static 将内部类静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性(静态成员不能访问非静态成员)
创建静态内部类对象的一般形式为:  外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()

 

 

 

例5.

public class Out {

	static class In{
		private static int a = 5;
		private int b = 9;
	}
	
	public void acc(){
		System.out.println(In.a);//通过类名访问静态内部类的类成员
		System.out.println(new In().b);//通过实例访问静态内部类的实例成员
	}
}

外部类不能直接访问静态内部类的成员

可以使用静态内部类的类名作为调用者来访问静态内部类的类成员  如  In.a

可以使用静态内部类对象作为调用者来访问静态内部类的实例成员  如  new In().b

 

 

 

 

 

 

匿名内部类

例6.

interface Product{
	public double getPrice();
	public String getName();
}

public class AnonymousTest {
	
public void test(Product p){
	System.out.println("购买了一个" + p.getName() + "花掉了" + p.getPrice());
}

public static void main(String[] args){
	AnonymousTest ta = new AnonymousTest();
	ta.test(new Product(){
		public double getPrice(){
			return 567.8;
		}
		public String getName(){
			return "AGP";
		}
	});
}
}


运行结果:购买了一个AGP花掉了567.8

 

例7.

abstract  class Device{
	private String name;
	public abstract double getPrice();
	public Device(){}
	public Device(String name){
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
}
public class AnonymousInner {

	public void test(Device d){
		System.out.println("购买了" +d.getName() + "价格是" +d.getPrice());
	}
	
	public static void main(String [] args)
	{
		
		AnonymousInner ai = new AnonymousInner();
		ai.test(new Device("电子示波器")
		{
			public double getPrice()
			{
				return 67.8;
			}
		});
		
		Device d = new Device()
		{
		
		{
					
			System.out.println("匿名内部类的初始化块");
		}
		
		public double getPrice()
		{
			return 56.2;
		}
		
		public String getName()
		{
			return "键盘";
		}
};
            ai.test(d);
	}
}

运行结果:

购买了电子示波器价格是67.8
匿名内部类的初始化块
购买了键盘价格是56.2

 

匿名内部类必须继承一个父类或实现一个接口,但最多只能两者选其一

定义匿名内部类的格式如下:

 

new 实现接口(){

 

}

 

new 父类构造器(实参){

 

}

 

 

例8.

interface A{
	void test();
}
public class ATest {
	
public static void main(String[] args){
	int age = 8;
	A a = new A(){
		public void test(){
			System.out.println(age);//从java8开始,匿名内部类,局部内部类允许访问非final的局部变量
		}
	};
	a.test();
}
}

运行结果:8(java8下,8之前会出现编译错误)

<span style="font-size:14px;">从java8开始,匿名内部类,局部内部类允许访问非final的局部变量</span>

 

 

参考资料http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.html

                       疯狂Java讲义

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值