java之内部类

内部类就是定义在另一个类中的类,使用内部类的理由主要有以下三点:

1)内部类方法可以访问该类定义在作用域中的数据,包括私有数据。

2)内部类可以对同一个包中的其他类隐藏起来。

3)当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。

内部类根据定义的位置不同,可以分为四种,第一种就是普通的内部类,第二种是局部内部类,第三种是匿名内部类,第四种是静态内部类。


这里只需强调一点即可,就是为了运行使用了其外部实例域的内部类,内部类对象中总有一个隐式引用,它指向了创建它的外部类对象,因此其内部类可以使用其外部类的实例域。

当然,既然有隐式引用,当然可以显式的表达出来了。

对于内部类引用外部类中数据,可以使用以下语法:外部类名.this.数据名

例如下面例子中的:

if(beep)可以显式的写为if(TalkingClock.this.beep)

创建一个内部类对象的时候也可以显式的说明,可以使用以下语法:内部类名 对象名=this.new 内部类名(参数);

例如下面例子中的:

ActionListener listener=new TimePrinter();可以显式的写为ActionListener listener=this.new TimePrinter();

下面是一个完整的例子:

代码:

package InnerClasses;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class InnerClassTest {
	public static void main(String[] args) {
		TalkingClock clock = new TalkingClock(1000,true);
		clock.start();
		
		JOptionPane.showMessageDialog(null,"关闭??");
		System.exit(0);
	}
}

class TalkingClock{
	private int interval;
	private boolean beep;
	
	public TalkingClock(int interval,boolean beep) {
		this.interval=interval;
		this.beep=beep;
	}
	
	public void start() {
		ActionListener listener=new TimePrinter();
		Timer t=new Timer(interval,listener);
		t.start();
	}
	
	private class TimePrinter implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			System.out.println("现在时间是:"+new Date());
			if(beep) {
				Toolkit.getDefaultToolkit().beep();
			}
		}
	}
}

运行结果:


对于第二种内部类--局部内部类,其实是定义在类方法中的内部类,这种类不能使用访问修饰符,而且这种类的作用域被限制在声明这个局部类的块中。同一般的内部类相比,局部内部类还有一个优势就是可以访问局部变量。

例如上面的代码可以修改为:

代码:

package InnerClasses;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class InnerClassTest {
	public static void main(String[] args) {
		TalkingClock clock = new TalkingClock(1000,true);
		clock.start();
		
		JOptionPane.showMessageDialog(null,"关闭??");
		System.exit(0);
	}
}

class TalkingClock{
	private int interval;
	private boolean beep;
	
	public TalkingClock(int interval,boolean beep) {
		this.interval=interval;
		this.beep=beep;
	}
	
	public void start() {
		
		class TimePrinter implements ActionListener{
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("现在时间是:"+new Date());
				if(beep) {
					Toolkit.getDefaultToolkit().beep();
				}
			}
		}
		
		ActionListener listener=new TimePrinter();
		Timer t=new Timer(interval,listener);
		t.start();
	}
}

输出结果和上一例子一样。


第三种内部类--匿名内部类:

这种内部类更加直接,没有类名。

具体语法为:

类名 对象名=new 类名(构造参数){

    内部类方法和数据

}

类名也可以是接口名,如果是接口名,则就像下面这样子了:

接口名 对象名=new 接口名(){

    方法和数据

}

下面是一个例子:

package InnerClasses;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class AnonyInnerClassTest {
	public static void main(String[] args) {
		TalkingClock2 clock =new TalkingClock2();
		clock.start(1000, true);
		JOptionPane.showMessageDialog(null, "退出??");
		System.exit(0);
	}
}

class TalkingClock2{
	public void start(int interval,boolean beep) {
		ActionListener listener=new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("现在的时间是:"+new Date());
				if(beep) {
					Toolkit.getDefaultToolkit().beep();
				}
			}
			
		};
		
		Timer t=new Timer(interval,listener);
		t.start();
	}
}

运行结果和前两个例子一样。


第四种内部类--静态内部类

静态内部类的目的很简单,就是为了把一个类隐藏在另一个类的内部。这时,可以将内部类声明为static。

静态内部类中不可以引用外部类的非静态变量和方法,而在静态内部类中可以有静态域和静态方法。

下面是一个例子:用于计算一个double型数组的最大值和最小值。

代码:

package InnerClasses;

public class StaticInnerClass {
	public static void main(String[] args) {
		double[] d=new double[20];
		for(int i=0;i<d.length;++i) {
			d[i]=100*Math.random();
		}
		ArrayAlg.Pair p=ArrayAlg.minmax(d);
		System.out.println("min="+p.getFirst());
		System.out.println("max="+p.getSecond());
	}
}

class ArrayAlg{
	public static class Pair{
		private double first;
		private double second;
		
		public Pair(double f,double s) {
			first=f;
			second=s;
		}
		
		public double getFirst() {
			return first;
		}
		
		public double getSecond() {
			return second;
		}
	}
	
	public static Pair minmax(double[] values) {
		double min=Double.POSITIVE_INFINITY;
		double max=Double.NEGATIVE_INFINITY;
		for(double v:values) {
			if(min>v)min=v;
			if(max<v)max=v;
		}
		return new Pair(min,max);
	}
}

运行结果:




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Kirito

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值