`
poyunri
  • 浏览: 29505 次
文章分类
社区版块
存档分类
最新评论

6.4 内部类

阅读更多
内部类:定义在一个类中的类。
为什么要用内部类:
1)内部类可以访问其外围类的实例域,包括私有数据。
2)内部类可以对同包中的其他类隐藏。
3)定义一个回调函数,使用匿名内部类要便捷。

6.4.1 使用内部类访问对象的状态
实例:一个TimePrinter常规类,他需要通过TalkingClock类的共有方法访问beep标志。
注释:TimePrinter类被声明为私有的,这样只有TalkingClock的方法才能生成TimePrinter对象。内部类可以是私有类,常规类只能是包可见性或公有可见性。
例6-4源代码:
package com.corejava.innerclass;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
/**
 * 
 * @author vincent
 * 
 */
public class InnerClassTest {

	public static void main(String[] args) {
		TalkingClock clock = new TalkingClock(1000, true);
		clock.start();
		
		JOptionPane.showMessageDialog(null, "Quit program?");
		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();
	}
	
	public class TimePrinter implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			Date now = new Date();
			System.out.println("At the tone, the time is " + now);
			if(beep)
				Toolkit.getDefaultToolkit().beep();
		}
		
	}
}

6.4.4局部内部类
使用背景:创建一个类的对象只需使用一次时,推荐使用局部内部类。例如上述代码中TimerPrinter这个类只在start方法中创建了对象并只使用了一次,这时可将TimerPrinter创建为局部内部类:
public void start() {
	class TimerPrinter implements ActionListener {
		public void actionPerformed(ActionEvent event) {
			Date now = new Date();
			System.out.println("At the tone, the time is " + now);
			if(beep)
				Toolkit.getDefaultToolkit().beep();
		}
	}
	
	ActionListener listener = new TimerPrinter();
	Timer t = new Timer(interval, listener);
	t.start();
}
注意:局部内部类不能用public或private声明,它的作用域被限定在声明这个局部类的块中;
局部类的好处是对外完全隐藏,即使TalkingClock类中的其他代码也不能访问它,除了start方法外,没有任何方法知道TimerPrinter类的存在。
局部类还有一个优点:除了能访问包含它的外部类,还能访问局部变量,不过这些局部变量必须被声明为final。

6.4.5由外部方法访问final变量
典型示例:将TalkingClock构造器的参数interval和beep移至start方法中。
public void start(int interval, final boolean beep) {
	class TimerPrinter implements ActionListener {
		public void actionPerformed(ActionEvent event) {
			Date now = new Date();
			System.out.println("At the tone, the time is " + now);
			if(beep)
				Toolkit.getDefaultToolkit().beep();
		}
	}
	
	ActionListener listener = new TimerPrinter();
	Timer t = new Timer(interval, listener);
	t.start();
}

6.4.6匿名内部类

1、将局部内部类深入,若只创建这个类的一个对象,就不用命名了。这种类就是匿名内部类。

小程序:

public void start(int interval, final boolean beep) {

ActiongListener listener = new ActionListener() {

public void actionPerformed(ActionEvent event) {

Date now = new Date();

System.out.println("At the tone, time is " + now);

if(beep)

Toolkit.getDefultToolkit().beep();

}

};

Timer t = new Timer(interval, listener);

t.start();

}

代码解析:创建了一个实现ActiongListener接口的类的新对象,这个新对象需要实现actionPerformed所定义的方法。

2、构造器的名字必须和类名相同,但是匿名类没有类名,所以匿名类没有构造器。取而代之的是将构造器的参数传递给超类(父类)构造器。尤其是内部类实现接口是不能有任何构造参数,而且还要提供一组括号,例如:

new InterfaceType() {

methods and data;

}

3、构造一个类的新对象共和构造一个匿名类的区别:

Person queen = new Person("Mary");//a Person object

Person count = new Person() {....}; //an object of an inner class extending Person

如果构造参数的闭源括号跟一个开花括号,表示正在定义的就是匿名内部类


例6-5源代码:将这个程序与之前的6-4相比较会发现匿名类的解决方案比较简单、实际和易于理解

package com.core.anonymousinnerclass;

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;

/**
 * 
 * @author vincent
 *
 */
public class AnonymousInnerClass {

	public static void main(String[] args) {
		TalkingClock clock = new TalkingClock();
		clock.start(1000, true);
		
		//keep progra running until user selects "OK"
		JOptionPane.showMessageDialog(null, "Quit program?");
		System.exit(0);
	}
}

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

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				Date now = new Date();
				System.out.println("At the tone, time is: " + now);
				if(beep)
					Toolkit.getDefaultToolkit().beep();
			}

		};
		Timer t = new Timer(interval, listener);
		t.start();
	}
}

6.4.7静态内部类
使用背景:只需要将一个类隐藏在另一个类的内部,并不需要内部类引用外围类对象时。
只有内部类可以声明为static,静态类除了不能生产外围类对象的引用外,与其他内部类一样。
例6-6
package com.core.staticinnerclass;

/**
 * 
 * @author vincent
 *
 */
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);	//不需要用new生成对象,静态方法可以直接引用
		
		System.out.println("min = " + p.getFirst());
		System.out.println("max = " + p.getSecond());
	}
			
}
	
	class ArrayAlg {

		//A pair of floating-point numbers
		public static class Pair {

			private double first;
			private double second;

			//Constructs a pair from two floating-point numbers
			public Pair(double f, double s) {
				first = f;
				second = s;
			}
			
			//Returns the first numbers of the pair
			public double getFirst() {
				return first;
			}
			
			//Return the second numbers of the pair
			public double getSecond() {
				return second;
			}
		}
		
		//minmax方法返回 Pair这个静态内部类
		public static Pair minmax(double[] values) {

			double min = Double.MAX_VALUE;
			double max = Double.MIN_VALUE;
			
			for (double v : values) {
				if (min > v)
					min = v;
				if (max < v)
					max = v;
			}
			return new Pair(min, max);
		}

	}


分享到:
评论

相关推荐

    Java2核心技术.part5

    6.4内部类 6.4.1使用内部类访问对象状态 6.4.2内部类的特殊语法规则 6.4.3内部类是否实用、必要和安全 6.4.4局部内部类 6.4.5匿名内部类 6.4.6静态内部类 6.5代理 第7章图形程序设计 7.1 ...

    Java2核心技术.part3

    6.4内部类 6.4.1使用内部类访问对象状态 6.4.2内部类的特殊语法规则 6.4.3内部类是否实用、必要和安全 6.4.4局部内部类 6.4.5匿名内部类 6.4.6静态内部类 6.5代理 第7章图形程序设计 7.1 ...

    Java2核心技术.part1

    6.4内部类 6.4.1使用内部类访问对象状态 6.4.2内部类的特殊语法规则 6.4.3内部类是否实用、必要和安全 6.4.4局部内部类 6.4.5匿名内部类 6.4.6静态内部类 6.5代理 第7章图形程序设计 7.1 Swing概述 ...

    Java2核心技术.part6

    6.4内部类 6.4.1使用内部类访问对象状态 6.4.2内部类的特殊语法规则 6.4.3内部类是否实用、必要和安全 6.4.4局部内部类 6.4.5匿名内部类 6.4.6静态内部类 6.5代理 第7章图形程序设计 7.1 ...

    Java2核心技术.part4

    6.4内部类 6.4.1使用内部类访问对象状态 6.4.2内部类的特殊语法规则 6.4.3内部类是否实用、必要和安全 6.4.4局部内部类 6.4.5匿名内部类 6.4.6静态内部类 6.5代理 第7章图形程序设计 7.1 ...

    Java2核心技术.part2

    6.4内部类 6.4.1使用内部类访问对象状态 6.4.2内部类的特殊语法规则 6.4.3内部类是否实用、必要和安全 6.4.4局部内部类 6.4.5匿名内部类 6.4.6静态内部类 6.5代理 第7章图形程序设计 7.1 ...

    KEPServerEX-6.4.321.0

    KEPServerEX-6.4.321.0 KEPServerEX V6的核心技术-OPC UA功能,能够满足用户的性能和可扩展性需求,并可以无缝接入工业物联网。发展内部Kepware技术工程师来深入了解OPC UA标准,可以更快地解决客户问题,并且更好地...

    KEPServerEX-6.4.321.0.rar 爆破版本

    KEPServerEX V6的核心技术-OPC UA功能,能够满足用户的性能和可...发展内部Kepware技术工程师来深入了解OPC UA标准,可以更快地解决客户问题,并且更好地支持终端用户。增加了Torque Tool 驱动对新款阿特拉斯设备的支持

    SANGFOR_AD_6.4_CONF_03_08_七层虚拟服务配置指导书.pdf

    七层反向代理,就是外部终端和AD建立起一个会话,AD和内部服务器再单独建立一个会话,达到隔离外部中断和内部服务器的目的,从而保证内部服务器的安全。

    NetGong v6.4

    NetGong 这款网络监视解决方案允许网络管理员、网站管理员和网络服务供应商监视因特网、企业内部网或者TCP/IP局域网上的任何网络设备并且在连接失败的时候通过可听见的警报、信息、电子邮件或者第三方软件立即收到...

    FastReport V6.4.12 VCL Enterprise(安装包源代码版含正版Key)

    FastReport V6.4.12 VCL Enterprise(安装包源代码版含正版Key),安装后,全部为源代码版。内含正版6.X正版安装序列号(授权码),内部使用请珍惜!当前官司最新版。支持Delphi 7-XE8, C++Builder 2005-XE8 and ...

    WinISO v6.4.0.5170.zip

    WinISO是一个 CD-ROM 映像文件格式转换工具...通过 WinISO,你可以在映像文件内部 添加/删除/重命名/提取 文件。 你可以将其他格式的映像文件转换为标准的 ISO 格式,同时你也可以从你的 CD-ROM 中创建 ISO 映像文件。

    入梦硬件检测工具箱v6.4 纯净版

    入梦工具箱是一款仿照图吧工具,且不报毒,永久免费分享,相比于图吧工具箱进行的创新,集成了数十款常用的硬件工具箱,包括常用的CPUZ,GPUZ,AIDA64等多款工具。...5.软件单文件也可以直接使用,内部的软件路径可以拖动自定义

    gradle-6.4-all.zip

    官方gradle-6.4-all.zip文件, 注意:解压后使用,内部附有使用说明;其他版本下载地址:https://blog.csdn.net/u013164293/article/details/110121086

    WinISO特别版v6.4.0.5136winiso简体中文汉化注册版

    winiso破解版是一个 CD-ROM 映像文件格式转换工具,并且可以直接编辑光盘映像文件。...通过 WinISO,你可以在映像文件内部 添加/删除/重命名/提取 文件。 你可以将其他格式的映像文件转换为标准的 ISO 格式,同时你

    serv-U 6.4

    用于搭建文件服务器,方便企业内部使用,可以方便的上传和下载资源

    Shader Control v6.4

    'Build View': 列出所有着色器(包括 Unity 内部着色器)及其关键字。 单击即可从构建过程中排除任何数量的着色器和/或关键字。 • 'Project View': 方便的统一视图,适用于项目中带源代码的所有着色器。 • 使用...

    易语言-精易模块6.4

    4、修复“类_json”-“加成员”命令参数变量的BUG导致命令失效的问题;感谢【@zyb1326711709 】反馈 5、修复“文件_删除配置项”参数名错别字问题;感谢【@纯情小黄牛 】反馈 6、修复“网页填表-网页_创建新网页”...

Global site tag (gtag.js) - Google Analytics