Java内部类

内部类是定义在其他类内部的类,其存在的原因

  1. 内部类对象能够访问创建它的对象的私有数据
  2. 能够隐藏起来,不为同一包中的其他类可见
  3. 可以方便地定义运行时回调
  4. 编写事件驱动的程序时用起来很方便
public class InnerClassTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BankAccount account = new BankAccount(10000);
		account.start(10);
		JOptionPane.showMessageDialog(null, "quit?");
		System.exit(0);
	}
}


class BankAccount{
	private double balance;
	
	public BankAccount(double b) {
		balance = b;
	}
	
	public void start(double rate) {
		ActionListener adder = new InterestAddr(rate);
		Timer t = new Timer(1000, adder);
		t.start();
	}
	
	//内部类是私有的
	private class InterestAddr implements ActionListener{
		private double rate;
		
		public InterestAddr(double r) {
			rate = r;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			//可以访问创建它的外部对象的数据字段
			double interest = balance * rate / 100;
			balance += interest;
			System.out.println("balance = " + balance);
		}
	}
}

内部类是私有的

编译器会把内部类编译成使用$分隔外部类名和内部类名的常规class文件

BankAccount$InterestAddr.class

 

局部内部类是定义在一个方法里的内部类

仔细观察BankAccount例子中的代码,发现只需要InterestAddr的名字的地方就是start方法,因此可以在方法里定义局部类

class BankAccount{
	private double balance;
	
	public BankAccount(double b) {
		balance = b;
	}
	
	public void start(double rate) {
		class InterestAddr implements ActionListener{
			private double rate;
			
			public InterestAddr(double r) {
				rate = r;
			}

			@Override
			public void actionPerformed(ActionEvent e) {
				//可以访问创建它的外部对象的数据字段
				double interest = balance * rate / 100;
				balance += interest;
				System.out.println("balance = " + balance);
			}
		}
		
		ActionListener adder = new InterestAddr(rate);
		Timer t = new Timer(1000, adder);
		t.start();
	}
}

局部类不会使用访问指示符(如public或者private)来声明,它的范围总是限定在声明它的程序块中。

相对于其他内部类而言,局部类还可以访问局部变量,不过,那些局部变量必须声明为final。

class BankAccount{
	private double balance;
	
	public BankAccount(double b) {
		balance = b;
	}
	
	public void start(final double rate) {
		class InterestAddr implements ActionListener{
			@Override
			public void actionPerformed(ActionEvent e) {
				//可以访问创建它的外部对象的数据字段
				double interest = balance * rate / 100;
				balance += interest;
				System.out.println("balance = " + balance);
			}
		}
		
		ActionListener adder = new InterestAddr();
		Timer t = new Timer(1000, adder);
		t.start();
	}
}

start控制流:

1)调用start方法

2)调用内部类InterestAddr的构造器初始化对象变量adder

3)把adder引用传递给Timer构造器,定时器启动,start方法退出。现在start方法的rate参数变量已经不存在了。

4)然后actionPerformed方法调用double interest = balance * rate / 100;

为了让actionPerformed方法中的代码能工作,InterestAddr类必然在释放start方法的局部变量rate之前给它做了一份拷贝,这也正是实际的情形。局部类的方法只能使用final的局部变量,因为这样的变量不能被修改,所以局部变量和局部类所建立的变量拷贝总是具有相同的值。

匿名内部类

对局部内部类的使用还可以走的更远,如果你只需要为内部类建立一个对象,那么甚至不必为该类指定一个名字。我们把这种类称作匿名内部类。

class BankAccount{
	private double balance;
	
	public BankAccount(double b) {
		balance = b;
	}
	
	public void start(final double rate) {
		ActionListener adder = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				double interest = balance * rate / 100;
				balance += interest;
				System.out.println("balance = " + balance);
			}
		};
		Timer t = new Timer(1000, adder);
		t.start();
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值