Java拾遗-内部类和匿名类
2015-09-05 21:20
543 查看
一、内部类
1. 内部类的定义:在A类的内部但是所有方法的外部定义一个B类,则B类就是A类的内部类,A是B的外部类。
2. 内部类访问原则
内部类的方法访问外部类所有的成员
外部类的方法不可以直接访问内部类的成员
内部类的优点:
可以让一个类方便的访问另一个类中的所有成员
增加程序的安全性,有效避免其他不相关类对该类的访问
何时使用内部类:
如果一个A类要使用B类的所有成员,并且A类不需要被B类以外的其他类访问,则我们应该把A类定义为B类的内部类。
二、匿名类
1. 匿名类是一种特殊的内部类
2. 如果一个方法内部定义了一个匿名类,则该匿名类可以访问:
外部类的所有成员
包裹该匿名类的方法中的所有final类型的局部变量
注意:非final类型的局部变量无法被匿名类访问
创建匿名类的三种方式
创建父类
实现接口
实现抽象类
创建匿名类之实现接口
4.创建匿名类之实现抽象类
5.创建匿名类之继承父类
6.匿名类的优缺点
如果一个类的语句比较少,逻辑比较简单,而且不经常变动,这时可以使用匿名类
如果一个类包含了重要的逻辑,将来要经常修改,则这个类就不应该当做匿名类使用,匿名类会导致代码的混乱。
1. 内部类的定义:在A类的内部但是所有方法的外部定义一个B类,则B类就是A类的内部类,A是B的外部类。
2. 内部类访问原则
内部类的方法访问外部类所有的成员
外部类的方法不可以直接访问内部类的成员
/* 本程序证明了: 内部类的所有方法都可以访问外部类的所有成员, 无论何种访问控制符,都可以,因为内部类被当作了外部类的一个成员 */ class A { private int j = 10; private void f() { System.out.println("FFFF"); } class B { private int k; //内部类的所有方法都可以访问外部类的所有成员,无论何种访问控制符,都可以,因为内部类被当作了外部类的一个成员 private void g() { System.out.println("j = " + j); //内部类的私有方法可以访问外部类的私有属性 f(); //内部类的私有方法可以访问外部类的私有方法 } } public void m() { B bb = new B(); bb.g(); } } public class TestInnerClass_1 { public static void main(String[] args) { A aa = new A(); aa.m(); } } /* 在JDK 1.6中的运行结果是: ---------- j = 10 FFFF ---------- */
class A{ private int i = 1; private void f(){ System.out.println("哈哈"); } //B是A的内部类 class B{ public int bi = 10; //非静态的内部类可以访问外部类所有的成员 public void g(){ System.out.printf("i = %d\n", i); f(); } } public void k(){ //g(); //error 外部类的方法不可以直接访问内部类的成员 //System.out.println(bi); //error 外部类的方法不可以直接访问内部类的成员 B bb = new B(); bb.g(); } } public class Test{ public static void main(String[] args){ A aa = new A(); aa.k(); } }
内部类的优点:
可以让一个类方便的访问另一个类中的所有成员
增加程序的安全性,有效避免其他不相关类对该类的访问
何时使用内部类:
如果一个A类要使用B类的所有成员,并且A类不需要被B类以外的其他类访问,则我们应该把A类定义为B类的内部类。
二、匿名类
1. 匿名类是一种特殊的内部类
2. 如果一个方法内部定义了一个匿名类,则该匿名类可以访问:
外部类的所有成员
包裹该匿名类的方法中的所有final类型的局部变量
注意:非final类型的局部变量无法被匿名类访问
import java.awt.*; import java.awt.event.*; public class TestWindow { public static void main(String[] args) { //如果把10行的final去掉,本程序在18行就会报错,因为匿名类只能访问包裹它的方法中的final类型的局部变量 final Frame f = new Frame(); //10行 f.setSize(200, 200); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { f.setVisible(false);//18行 System.exit(-1); } } ); f.setVisible(true); } }
创建匿名类的三种方式
创建父类
实现接口
实现抽象类
创建匿名类之实现接口
/* 假设A是接口名 new A() { 实现接口中方法的代码 }; 功能:生成一个实现了A接口的匿名类对象 */ interface It { void f(); //void g(); // 如果该语句生效的话,21行到27行的代码中就必须的实现g方法 } public class TestAnonyClass_1 { public static void main(String[] args) { It it = new It() { //21行 public void f() { System.out.println("哈哈"); } }; //27行 //error // It it = new It1() // ( //是{ 不是( // public void f() // { // System.out.println("哈哈"); // } // ); // 是} 不是) //error // It it = new It() // ( // { // public void f() // { // System.out.println("哈哈"); // } // } // ; it.f(); } }
4.创建匿名类之实现抽象类
/* 假设A是抽象类 new A() { 实现了A类的所有抽象类的方法代码 添加自己的方法或属性代码【不建议,因为没有实际意义】 } 功能: 生成一个匿名类,该匿名类必须得实现了A类的所有抽象方法, 当然该匿名类也可以定义自己的属性和方法 */ abstract class A { abstract public void f(); public void g() { } } public class TestAnonyClass_2 { public static void main(String[] args) { A aa = new A() { //f方法不可以被注释掉, 因为f是抽象方法,匿名类必须的实现 public void f() { System.out.println("FFFF"); } //g方法可以被注释掉 public void g() { System.out.println("GGGG"); } public void k() { } }; aa.f(); aa.g(); //aa.k(); } } /* 在JDK 1.6中的运行结果是: ----------------------------- FFFF GGGG ----------------------------- */
5.创建匿名类之继承父类
/* 假设A是个类名 new A() { 重写了A类的方法代码 自己添加的属性和方法【【不建议,因为没有实际意义】】 } 功能: 生成一个A类的子类对象,该匿名类对象继承了A的所有非private成员 */ class A { public void f() { System.out.println("哈哈"); } } public class TestAnonyClass_3 { public static void main(String[] args) { A aa = new A() { //重写了父类A的方法 public void f() { System.out.println("嘿嘿"); } //可以定义自己的方法,但没有任何实际意义 public void g() { System.out.println("GGGG"); } }; aa.f(); //aa.g(); //error } } /* 在JDK 1.6中的运行结果是: ----------------------------- FFFF GGGG ----------------------------- */
6.匿名类的优缺点
如果一个类的语句比较少,逻辑比较简单,而且不经常变动,这时可以使用匿名类
如果一个类包含了重要的逻辑,将来要经常修改,则这个类就不应该当做匿名类使用,匿名类会导致代码的混乱。
相关文章推荐
- 搭建eclipse的javaWeb开发环境
- spring4泛型注入
- java异常处理一
- eclipse启动报i386\jvm.cfg
- java下DataInputStream与DataOutputStream写入数据的同时写入数据类型
- Spring MVC学习
- SpringMVC上传文件实例
- Servlet+JSP+JavaBean开发模式(MVC)介绍
- get请求中文乱码,思考为什么要用两次的encodeURI()
- Eclipse添加Android项目工程后res文件夹下layout/values/drawable文件不可见
- java下管道流 PipedOutputStream 与PipedInputStream
- java.xml
- Java Web乱码问题
- Java复习
- Spring常用注解
- 排序算法之Java实现7——希尔排序算法
- 排序算法之Java实现6——简单选择排序算法
- 排序算法之Java实现5——快速排序算法
- 排序算法之Java实现4——二路归并排序算法
- 排序算法之Java实现3——直接插入排序算法