书接上文
静态内部类
在一个类内部定义一个静态内部类:
静态的含义是该内部类可以像其他成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。下面代码我们重点看有关Inner3的代码:
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();
outer.innerPrint();
outer.show();*/
Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
n.print();
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类
{
int x = 10;
class Inner2//
{
public void print()
{
//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
System.out.println("方法内部类"+x);
}
}
Inner2 inner2 = new Inner2();//增加这行跟下面这行
inner2.print();
}
static class Inner3
{
public void print()
{
System.out.println("这是静态内部类");
}
}
}
/*
结果:
这是静态内部类
*/
这样写的目的就是基于封装的概念,内部类跟外部类之间一定是有关系的,否则不会出现内部类概念。比如你家里的亲戚能住在你家,一般大街上一个人能随便让他住在自己家吗?说是有相对关系,只不过,这个相对关系比较独立,这个内部类附属在外部类里面,有一定的关系,但是没有实际上的代码调用关系,这就是封装。刚才说了,在静态内部类里面是不能访问外部类的属性的(在普通内部类和方法内部类可以),因为静态类里面只能访问静态变量。
匿名内部类
匿名内部类就是没有名字的内部类。
匿名内部类三种情况:
(1)继承式的匿名内部类;
(2)接口式的匿名内部类;
(3)参数式的匿名内部类。
先看继承式匿名内部类:
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();
outer.innerPrint();
outer.show();
Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
n.print();*/
outer.print1();
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类
{
int x = 10;
class Inner2//
{
public void print()
{
//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
System.out.println("方法内部类"+x);
}
}
Inner2 inner2 = new Inner2();//增加这行跟下面这行
inner2.print();
}
static class Inner3
{
public void print()
{
System.out.println("这是静态内部类");
}
}
public void print1()//继承式匿名内部类
{
Cat cat = new Cat()//新建一个对象
{
public void eat()
{//加大括号,表示实现
System.out.println("cat:匿名继承内部类");
}
};//这里一定要加分号,从61行到这一行是一条语句。
cat.eat();
}
}
abstract class Cat//抽象类,下面要有抽象方法,应加abstract
{
public abstract void eat();
}
/*
结果:
cat:匿名继承内部类
*/
//这个内部类创建以后,也会产生成一个Outer$1.class文件
然后是接口式匿名内部类:
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();
outer.innerPrint();
outer.show();
Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
n.print();*/
outer.print1();
outer.print2();
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类
{
int x = 10;
class Inner2//
{
public void print()
{
//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
System.out.println("方法内部类"+x);
}
}
Inner2 inner2 = new Inner2();//增加这行跟下面这行
inner2.print();
}
static class Inner3
{
public void print()
{
System.out.println("这是静态内部类");
}
}
public void print1()//继承式匿名内部类
{
Cat cat = new Cat()//新建一个对象
{
public void eat()
{//加大括号,表示实现
System.out.println("cat:匿名继承内部类");
}
};//这里一定要加分号,从61行到这一行是一条语句。
cat.eat();
}
public void print2()//接口式匿名内部类
{
Eat eat = new Eat()//接口是不能被新建的,所以我们加了个大括号,来实现这个接口,然后,大括号后面记得要加分号
{
public void eat()
{
System.out.println("cat:匿名接口式内部类");
}
};
eat.eat();
}
}
interface Eat
{
public void eat();
}
abstract class Cat//抽象类,下面要有抽象方法,应加abstract
{
public abstract void eat();
}
/*
结果:
cat:匿名继承内部类
cat:匿名接口式内部类
*/
//再创建这个匿名内部类时,就又会生成一个Outer$2.class文件
然后是参数是内部类
public class Demo1
{
public static void main(String[] args)
{
Outer outer = new Outer();
//在外部创建成员内部类的实例:
/*Outer.Inner inner =outer.new Inner();
//调用内部类方法:
inner.print();
outer.innerPrint();
outer.show();
Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
n.print();*/
outer.print1();
outer.print2();
outer.print3(new Eat()
{
public void eat()//方法在这里写
{
System.out.println("参数式匿名内部类");//这里不要加eat了,会提示错误: 找不到符号
}
});//也可以传多个参数,中间加逗号,那样写就比较复杂了
}
}
class Outer
{
private String name;
//添加这个方法:
public void innerPrint()
{
Inner inner = new Inner();
inner.print();
}
private class Inner//成员内部类
{
public void print()
{
System.out.println("成员内部类");
}
}
public void show()//方法内部类
{
int x = 10;
class Inner2//
{
public void print()
{
//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
System.out.println("方法内部类"+x);
}
}
Inner2 inner2 = new Inner2();//增加这行跟下面这行
inner2.print();
}
static class Inner3
{
public void print()
{
System.out.println("这是静态内部类");
}
}
public void print1()//继承式匿名内部类
{
Cat cat = new Cat()//新建一个对象
{
public void eat()
{//加大括号,表示实现
System.out.println("cat:匿名继承内部类");
}
};//这里一定要加分号,从61行到这一行是一条语句。
cat.eat();
}
public void print2()//接口式匿名内部类
{
Eat eat = new Eat()//接口是不能被新建的,所以我们加了个大括号,来实现这个接口,然后,大括号后面记得要加分号
{
public void eat()
{
System.out.println("cat:匿名接口式内部类");
}
};
eat.eat();
}
public void print3(Eat eat)//参数式匿名内部类,要往方法里传一个参数(把接口当参数)
{
eat.eat();
}
}
interface Eat
{
public void eat();
}
abstract class Cat//抽象类,下面要有抽象方法,应加abstract
{
public abstract void eat();
}
/*
结果:
cat:匿名继承内部类
cat:匿名接口式内部类
参数式匿名内部类
*/
在使用匿名内部类时,要记住以下几个原则:
(1)不能有构造方法,只能有一个实例
(2)不能定义任何形态成员、静态方法
(3)不能是public、protected、private、static
(4)一定是在new的后面,用其隐含实现一个接口或继承一个类
(5)匿名内部类为局部的,所以局部内部类的所有限制都对其生效