InnerClass
内部类:在一个类(外围类OuterClass)中定义另一个类(内部类InnerClass),借用其他博主的举例,外围类是人,人由各个器官组成,如心脏,内部类是心脏,心脏有自己的属性和方法,同时也可以访问身体的属性。InnerClass可以分成四大类:成员内部类、局部内部类、匿名内部类、静态内部类。
1、成员内部类
package com.yuan.test;
public class MerberInnerClass {
/**
* @param args
*/
private String name;
public int iNumber;
MerberInnerClass(String name, int iNumber) {
this.name = name;
this.iNumber = iNumber;
}
public void fun() {
System.out.println("hello");
}
public class InnerClass {
private int number = 0;
public int iNumber = 2;
public String getName() {
return name;
}
public int getNumber() {
return number;
}
public void fun() {
int iNumber = 3;
System.out.println("local variable is :" + iNumber);
System.out.println("inner variable is :" + this.iNumber);
System.out.println("outer variable is :"
+ MerberInnerClass.this.iNumber);//外围类域访问格式:OuterClass.this.field
MerberInnerClass.this.fun();//外围类方法访问格式:OuterClass.this.method
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MerberInnerClass merber = new MerberInnerClass("Estelle", 1);
MerberInnerClass.InnerClass inner = merber.new InnerClass();// 外围类引用内部类格式:outerObject.new InnerClass();
System.out.println("private name is :" + inner.getName());// 内部类可以访问外围内作用域中数据
System.out.println("private number is :" + inner.getNumber());
inner.fun();
}
}
运行结果:
private name is :Estelle
private number is :0
local variable is :3
inner variable is :2
outer variable is :1
hello
成员内部类有以下特性:
- 内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。外部类只能被public和包访问两种权限修饰
- 可访问外围类的所有成员属性和方法
- 成员内部类不存在任何static的变量和方法,个人理解是:成员内部类需访问外围类数据,即先有外围类后有内部类,所以内部类不存在static变量或方法
2、局部内部类(Local Inner Class)
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
package com.yuan.TalkClock;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.Timer;
public class TalkingClock {
public TalkingClock() {
// TODO Auto-generated constructor stub
}
public void start(int interval, final boolean beef) {//局部内部类可以访问外围类中修饰符为final的局部变量
class TimePrinter implements ActionListener {//局部内部类不能被申明为private、public
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Date now = new Date();
System.out.println("At the tone:" + now);
if (beef)
Toolkit.getDefaultToolkit().beep();
}
}
ActionListener listener = new TimePrinter();
Timer t = new Timer(interval, listener);
t.start();
}
}
局部内部类有以下特性:- 局部类不能用public或private访问修饰符声明,原因:类修饰符只能为public、private、final,局部变量修饰符只能为final
- 对同一个包中的其他类隐藏起来
- 不仅能访问外部类,也可以访问被final修饰的局部变量
为什么只能访问final修饰的局部变量?因为内部类代码实际访问的是新增构造器传入外部本地变量值的复制,即在构造其中新增一个特殊字段,在内部类中修改新增字段并不能反馈到郑重的外部类本地变量中,为了保证修改变量的一致性,选择final修饰符确保变量同步性
3、匿名内部类
public class OuterClass {
private String name ;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
class InnerClass{
public InnerClass(){
name = "chenssy";
age = 23;
}
}
}
匿名内部类特性:借用think in java- 内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
- 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
- 创建内部类对象的时刻并不依赖于外围类对象的创建。
- 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
- 内部类提供了更好的封装,除了该外围类,其他类都不能访问。
4、静态内部类
只需要将一个类隐藏到另一类中,不需要内部类引用外围类,则可以使用static Inner Class,俗称嵌套内部类。用static 将内部内静态化,内部类就只能访问外部类的静态成员变量,可以直接用OuterClass.InnerClass。
package com.yuan.test;
public class Out {
/**
* @param args
*/
private static int age = 12;
public static class In {
public static void print() {
System.out.println(age);
}
}
public static void main(String[] args) {
Out.In in = new Out.In();
in.print();
}
}
运行结果:12