`
riyunzhu
  • 浏览: 28780 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

java中的内部类详解和应用

 
阅读更多

今天写程序的时候,碰到了一个内部类。该内部类调用了外部类的自身对象。因为之前对外部类没有什么理解,刚碰到这样的问题,先是去看书上有没有详细的介绍,但是很遗憾没有。只有从网上去找了相关的资料看看。下面这个例子发现很好,就转过来,,希望对大家有所帮助。也算对自己学习的一个标记!

eg code:

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

/**
 * java内部类
 * 
 * 内部类是指在一个外部类的内部在定义一个类
 * 内部类作为外部类的一个成员,并且依附外部类而存在。
 * 内部类可以为静态,可用protected和private修饰(而外部类不可以,外部类只能用public和default)。
 * 分类:成员内部类、局部内部类、静态内部类、匿名内部类。
 * @author Administrator
 *
 */
public class Outer {
	/**
	 * 成员内部类 代码
	 */
	private static int i=1;
	private int j=10;
	private int k=20;
	public static void outer_f1(){
		
	}
	public void outer_f2(){
		
	}
	/**
	 * 外部类的非静态方法访问成员内部类
	 */
	public void outer_f3(){
		Inner inner=new Inner();
		inner.inner_f1();
	}
	
	/**
	 * 外部类的静态方法访问成员内部类
	 */
	public static void  outer_f4(){
		//step1 建立外部类对象
		Outer outer=new Outer();
		//step2 根据外部类对象建立内部类对象
		Inner inner=outer.new Inner();
		//step3 访问内部类方法
		inner.inner_f1();

	}
	
	/**
	 * 成员内部类
	 * 作为外部类的一个成员存在,与外部类的属性、方法并列。
	 * 优点:
	 * 1、内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使声明为private,但是对于处于其内部的内部类还是可见的。)
	 * 2、可以内部类定义在外部类不可访问的属性。这样就在外部类中实现了比外部类private还要小的额访问权限。
	 * 注意:
	 * 1、内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。
	 * 	  对于一个名为Outer的外部类和其内部定义的名为Inner的内部类。编译完成后出现Outer.class 和 Outer$Inner.class 两个类
	 * 2、当Outer是一个private类时,外部类对于其外部访问是私有的,所以就无法建立外部类对象,进而也无法建立内部类对象。
	 * @author Administrator
	 *
	 */
	class Inner{
		//static int inner_i=100; 内部类中不允许定义静态变量,内部类作为外部类的一个成员,成员内部不允许定义静态变量.
		 int j=100;//内部类和外部类的实例变量可以共存
		private int inner_i=1;
		
		void inner_f1(){
			System.out.println(inner_i);
			System.out.println(j);//在内部类中访问内部类自己的变量直接使用变量名
			System.out.println(this.j);//或者使用this.变量名
			System.out.println(Outer.this.j);//在内部类中访问外部类中与内部类同名的实例变量 用外部类名.this.变量名
			System.out.println(k);//如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类变量
			outer_f1();
			outer_f2();
		}
	}
	
	
	/**
	 * 局部内部类代码
	 */
	
	private int s=100;
	private int out_i=1;
	
	public void outer_f5(final int k){
		final int s=200;
		int i=1;
		final int j=10;
		/**
		 * 局部内部类
		 * 在方法中第一的内部类称为局部内部类。
		 * 与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块
		 * 注意:
		 * 1、在类外不可直接生产局部内部类(保证局部内部类对外是不可见的)。
		 * 2、要想使用局部内部类时需要生产对象,对象调用方法,在方法中才能调用局部内部类。
		 * 3、通过内部类和接口达到一个强制的弱耦合,用局部内部类来实现接口,并在方法中返回接口类型,使局部内部类不可见,屏蔽实现类的可见性。
		 * @author Administrator
		 *
		 */
		class Inner{
			int s=300;//可以定义与外部类同名的变量
		  //static int m=20;不可以定义静态变量
			/**
			 * 内部类构造函数
			 */
			Inner(int k){
				inner_f(k);
			}
			int inner_i=100;
			/**
			 * 内部类的方法
			 * @param k
			 */
			void inner_f(int k){
				System.out.println(out_i);//如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量
				System.out.println(j);//可以访问外部内的局部变量(即方法内的变量,但是变量必须是final)
				System.out.println(s);//如果内部类中有与外部类同名的变量,直接用变量名访问的是内部类的变量
				System.out.println(this.s);//用this.变量名 访问的也是内部类变量
				System.out.println(Outer.this.s);///用外部类名.this.内部类变量名 访问的是外部类变量
			}
		}
		
		new Inner(k);
	}
	
	/**
	 * 静态内部类代码
	 * 注意:
	 * 前三种内部类与变量类似,所以可以对照参考变量
	 */
	private static int a=1;
	private int b=10;
	public static void outer_f6(){
		
	}
	public void outer_f7(){
		
	}
	/**
	 * 静态内部类
	 * 静态内部类可以使用public,protected,private修饰
	 * 静态内部类中可以定义静态和非静态的成员
	 * 注意:
	 * 一个静态内部类不需要一个外部类的成员:只是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成
	 * Outer.Inner2 in=new Outer.Inner2();
	 * 这实际上静态内部类成为了一个顶级类。
	 * 静态内部类不可用private来进行定义。
	 * 当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用内部类来实现。用接口不能完全地实现多继承,用接口配合内部类才能实现真正的多继承。
	 * 例子:class People{ run(); } interface Machine{ run(); } class Robot extends People implement Machine
	 * @author Administrator
	 *
	 */
	static class Inner2{
		static int inner_i=100;
		int inner_j=200;
		static void inner_f1(){
			
			System.out.println("Outer.a:"+a); //静态内部类只能访问外部类的静态成员
			outer_f6();//包括静态变量和静态方法
		}
		void inner_f2(){
			//System.out.println("Outer.b:"+b); 静态内部类不能访问外部类的非静态成员
			//outer_f7(); X 包括非静态变量和非静态方法
		}
	}
	/**
	 * 外部类访问静态内部类
	 */
	public void outer_f8(){
		//外部内访问内部类的静态成员:内部类.静态成员
		System.out.println(Inner2.inner_i);
		Inner2.inner_f1();
		//外部类访问内部类非静态成员:实例化内部类
		Inner2 inner=new Inner2();
		System.out.println(inner.inner_j);
		inner.inner_f2();

	}
	/**
	 * 匿名内部类
	 * 
	 * 匿名内部类就是没有名字的内部类。
	 * 注意:
	 * 1、匿名内部类不能有构造函数
	 * 2、匿名内部类不能定义任何静态成员、方法和类
	 * 3、匿名内部类不能是public、protected、private、static
	 * 4、只能创建匿名内部类的一个实例
	 * 5、一个匿名内部类一定是在new后面,用其隐含实现一个接口或实现一个类。
	 * 6、因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效
	 * @return
	 */
	public Contents outer_f9(){
		
		return new Contents (){
			private int i=10;
			@Override
			public int getValue() {
				// TODO Auto-generated method stub
				return i;
			}
			
		};//在匿名内部类末尾的分号,并不是用来标记此内部类结束(C++中是那样)。实际上,它标记的是表达式的结束,只不过这个表达式正巧包含了内部类罢了。因此,这与别的地方使用的分号是一致的。  
		
		//等同于
//		class MyContents implements Contents {
//			private int i=10;
//			@Override
//			public int getValue() {
//				// TODO Auto-generated method stub
//				return i;
//			} 
//			
//		} 
//		return new MyContents();
	}
	public Wrapping outer_f10( int x){
		final int z=x;
		return new Wrapping(x){
			public void  dest(){
				System.out.println("outer_f10: "+z);//可以访问外部内的局部变量(即方法内的变量,但是变量必须是final)
			}
		};
	}
	public static void main(String[] args){
		
		outer_f4();//成员内部类
		new Outer().outer_f5(4);//局部内部类
		new Outer().outer_f8();//静态内部类
		new Outer().outer_f9().getValue();//匿名内部类
		new Outer().outer_f10(8).dest() ;//匿名内部类
		InnerClassTest obj=new InnerClassTest();
		obj.launchFrame();
	}
	
}
/**
 * 一个内部类的简单应用
 * 
 * @author Administrator
 *
 */
class InnerClassTest{
	private Frame f;
	private TextField tf;
	public InnerClassTest(){
		f=new Frame("Inner classes example");
		tf=new TextField(30);
	}
	public void launchFrame(){
		Label label=new Label("Click and drag the mouse");
		f.add(label,BorderLayout.NORTH);
		f.add(tf,BorderLayout.SOUTH);
		//成员内部类
		f.addMouseMotionListener(new MyMouseMotionListener());/*参数为内部类对象*/
		//等效 匿名内部类
//		f.addMouseMotionListener(new MouseMotionAdapter(){
//			public void mouseDragged(MouseEvent e) {
//				String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();
//				tf.setText(s);
//			}
//			
//		});
		f.setSize(300,200);
		f.setVisible(true);
	}
	
	class MyMouseMotionListener extends MouseMotionAdapter{ /*内部类开始*/
		public void mouseDragged(MouseEvent e) {
			String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();
			tf.setText(s); }
		}
	//内部类结束
}


interface Contents{
	int getValue();
}
class Wrapping{
	int j;
	Wrapping(int i){
		j=i;
	}
	public void dest(){
		System.out.println("Wrapping:"+j);
	}
}

转载来自于:http://www.iteye.com/topic/1116446
分享到:
评论

相关推荐

    Java内部类应用详解

    从Java1.1开始引入了内部类以来,它就引起了人们的激烈争论。其实任何优秀的语言特性用得不好就是滥用,内部类用得不好就会导致代码像迷宫一样,导致出现毫无重用的综合征。...本文档讲述Java内部类的规则及应用

    java内部类应用详解

    java内部类的详细应用总结,也是对java多一些了解,希望对初学java的有用,也有所启发

    Java Web开发详解:XML+DTD+XML Schema+XSLT+Servlet3.0+JSP2.2深入剖析与实例应用/孙鑫编著

    鑫编写的《Java Web开发详解——XML+DTD+XML Schema+XSLT+Servlet3.0+JSP2.2深入剖析与实例应用》共分4篇,从XML、XML Schema、XSLT、Servlet、JSP和应用的角度向读者展示了Java Web开发中各种技术的应用,循序渐进...

    Java开发详解.zip

    031503_【第15章:Java反射机制】_反射应用——取得类的结构笔记.pdf 031504_【第15章:Java反射机制】_Java反射机制的深入研究笔记.pdf 031505_【第15章:Java反射机制】_动态代理笔记.pdf 031506_【第15章:Java...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    java线程池ThreadPoolExecutor类使用详解.docx

    在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了...

    (超赞)JAVA精华之--深入JAVA API

    2.4 Java Web应用中的任务调度 2.5 用连接池提高Servlet访问数据库的效率 2.6 应用服务器的集群策略及Java EE 5.0 2.7 Servlet中的Listener的应用 2.8 JSTL(JSP标准标签库)介绍 3 JAVA扩展 3.1 Log4j基本使用方法 ...

    Java匿名内部类原理与用法详解

    主要介绍了Java匿名内部类原理与用法,结合实例形式分析了Java匿名内部类的概念、原理、应用与相关操作注意事项,需要的朋友可以参考下

    java基础案例与开发详解案例源码全

    8.1 内部类和内部接口202 8.1.1 非静态成员内部类203 8.1.2 局部内部类206 8.1.3 静态内部类209 8.1.4 匿名内部类211 8.2 对象包装器213 8.3 装箱和拆箱216 8.4 本章习题218 第9章 9.1 String类220 9.1.1 字符串常量...

    JAVA SE学习精华集锦

    2.4 Java Web应用中的任务调度 96 2.5 用连接池提高Servlet访问数据库的效率 99 2.6 应用服务器的集群策略及Java EE 5.0 111 2.7 Servlet中的Listener的应用 112 2.8 JSTL(JSP标准标签库)介绍 115 3 JAVA扩展 119 ...

    《精通Spring2.X企业应用开发详解》随书源码1-15章

    使用JPA访问数据库 第12章 整合其他ORM框架 第4篇 业务层应用 第13章 任务调度和异步执行器 第14章 JavaMail发送邮件 第15章 在Spring中使用JMS 第16章 在Spring中开发Web Service 第17章 使用...

    Java 基础核心总结 +经典算法大全.rar

    节点流和处理流 Java IO 的核心类 File Java IO 流对象 字节流对象InputStream OutputStream 字符流对象Reader Writer 字节流与字符流的转换新潮的 NIO 缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO ...

    疯狂JAVA讲义

    学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在子类中再定义一个内部类来重写其父类中的内部类? 211 6.7.4 局部内部类 211 6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 ...

    《精通Spring2.X企业应用开发详解》16-19章

    使用JPA访问数据库 第12章 整合其他ORM框架 第4篇 业务层应用 第13章 任务调度和异步执行器 第14章 JavaMail发送邮件 第15章 在Spring中使用JMS 第16章 在Spring中开发Web Service 第17章 使用...

Global site tag (gtag.js) - Google Analytics