一、成员内部类
package 类不类;
class Test{
public static void main(String[] args){
MenberInnerClass out=new MenberInnerClass();
out.eat();
MenberInnerClass.inner in=new MenberInnerClass().new inner();
in.eat();
}
}
/**
* 成员内部类
* @author Administrator
*
*/
public class MenberInnerClass {
public String name="呵呵";
public void eat(){
System.out.println("吃鱼肉");
//可以根据构建对象的方法在外部类中使用内部类的属性和方法
inner in=new inner();
in.sing();
}
public void play(){
System.out.println("打篮球去了");
}
public class inner{
public int age=50;
public void eat(){
System.out.println("吃鸭肉");
}
public void sing(){
System.out.println("唱歌");
//可以通过构建外部类的对象在内部类中调用外部类的属性和方法
MenberInnerClass out=new MenberInnerClass();
//也可以使用类名.this.属性名(方法名)来调用外部类的属性和方法
System.out.println(MenberInnerClass.this.name);
System.out.println(out.name);
}
}
}
二、静态内部类
package 类不类;
//静态内部类
public class StaticInnerClass {
public static void main(String[] args){
out o=new out();
o.eat();
System.out.println(o.i);
//因为此类被static关键字修饰,在java编译器的时候就已经编译好了
//所以可以直接当做一般类对待
//Right:in i=new in();
out.in i=new out.in();
i.play();
}
}
class out{
int i=23;
static int m=0;
public void eat(){
in ii=new in();
System.out.println(ii.i);
ii.play();
System.out.println("吃鱼咯");
}
//内部类是可以被static关键字修饰的,叫做静态内部类
public static class in{
int i=59;
public void play(){
out oo=new out();
//oo.eat();
/**
* 在静态内部类中调用外部类的属性和方法有两种方式:
* 第一种:在内部类构建外部类的对象,然后调用对象的属性和方法
* 第二种:把外部类的属性和方法用static关键字修饰,然后通过静态方式访问
*/
System.out.println(out.m);
System.out.println(oo.i);
System.out.println("打篮球去了");
//重点:在static代码块中不能使用this关键字
//System.out.println(out.this.m);
}
}
}
三、方法内部类
package 类不类;
//方法内部类
public class MethordInnerClass {
public static void main(String[] args){
Outer o=new Outer();
System.out.println(o.a);
o.eat();
o.play();
}
}
class Outer{
final int a=99;
public void eat(){
System.out.println("吃鸡腿");
}
public void play(){
final int b=34;
class Inner{
/**
* 在局部内部类中不能使用static关子健
*/
int c=45;
public void sing(){
System.out.println("唱中文歌");
System.out.println(Outer.this.a);
System.out.println(b);
System.out.println(c);
}
}
Inner in=new Inner();
in.sing();
}
}
/**
* (1)所谓“局部内部类”就是在对象的方法成员内部定义的类,而方法中的类,
* 访问同一个方法中的局部变量,却必须要加一个final
* (2)原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命周期,
* 局部变量的生命周期:当方法被调用时,该方法中的局部变量在檡中被创建,
* 当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命周期,
* 与其他类一样,当创建一个局部内部类对象后,只有当他没有其他人在引用他时,他才能死亡
* 所以完全可能一个方法已经调用结束(局部变量已死亡),当该局部变量对象依然活着,
* 即:局部类的对象生命周期会超过局部变量。
* (3)局部内部类的对象访问同一个方法中的局部变量,那么这就要求只要局部内部类对象还活着,那么栈中的那些他要
* 访问的局部变量就不能死亡(否则:他都死了,还访问什么呢?)。这就是说:局部变量的生命周期至少等于或者
* 大于局部内部类对象的声明周期。
* (4)解决方法:局部内部类的对象可以访问同一个方法中被定义为final的局部变量。定义final后,编译程序的实现
* 方法:将所有的局部内部类对象要访问的final型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使
* 栈中的局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以
* 访问final型局部变量。
* (5)归纳总结:局部内部类对象中包含要访问的final型局部变量的一个拷贝,成为他的数据成员。因此,正是在这个意义上,
* final型局部变量的生命周期,超过其方法的一次调用。严格来说,方法调用结束,所有的局部变量全死亡了,但:
* 局部内部类对象中有final型局部变量的拷贝
*
*/
四,匿名内部类
(1)第一种
package 类不类;
public class LimingInnerClass {
public static void main(String[] args){
Caculute can=new Caculute(){
@Override
public void add(int a,int b){
System.out.println(a+b);
}
@Override
public void sub(int a,int b){
System.out.println(a-b);
}
};
can.add(3, 5);
can.sub(54, 32);
}
}
interface Caculute{
public void add(int a,int b);
public void sub(int a,int b);
}
(2)第二种
package 类不类;
import java.util.Date;
public class NimingInnerClass {
@SuppressWarnings("deprecation")
public String getDate(Date date){
return date.toLocaleString();
}
public static void main(String[] args){
NimingInnerClass outer=new NimingInnerClass();
Date date=new Date();
String str=outer.getDate(date);
System.out.println(str);
System.out.println("***************************");
@SuppressWarnings("serial")
String s=outer.getDate(new Date(){
@Override
public String toLocaleString(){
return "I will change";
}
});
System.out.println(s);
}
}