内部类的章节看了两遍…总忘,看完总是记不起来有哪些知识点。只好总结一下了。
内部类作为public成员
public class Main {
public static void main(String args[])
{
/*输出inner1里的run1()*/
outer.inner1 in1=new outer().new inner1();
in1.run1();
/*输出inner1里的run1()*/
outer out=new outer();
out.viewInner1();
/*输出run2()*/
outer.inner2 in2=new outer.inner2();
in2.run2();
/*输出run3()*/
outer.inner2.run3();
}
}
class outer
{
static int x=4;
/*共有化内部类*/
public class inner1
{
void run1()
{
System.out.println("run1:x="+x);
}
}
void viewInner1()
{
inner1 in=new inner1();
in.run1();
}
/*静态内部类*/
static class inner2/*暂时先当成当成静态成员方法,以后再细究*/
{
void run2()
{
System.out.println("run2:x="+x);//int x 前面需要加static修饰
}
static void run3()
{
System.out.println("run3:x="+x);//int x 前面需要加static修饰
}
}
}
内部类访问外部类
public class M1 {
public static void main(String[] args) {
/*1*/
A a=new A();
a.run();
/*2*/
A.B b=new A().new B();
b.run();
}
}
class A
{
int x=1;
class B
{
int x=2;
void run()
{
int x=3;
System.out.println(A.this.x);
System.out.println(this.x);
System.out.println(x);
}
}
void run()
{
B b=new B();
b.run();
}
}
局部内部类
毕向东的源代码,简洁明了
/*
class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner //extends Object
{
//覆盖了toString方法。
public String toString()
{
return "tostring:"+y;//假设可以访问y。
}
}
obj = new Inner();//给obj复制一个Inner对象。
}
public void function()//延长了方法的生命周期,导致y无法访问。出错。
{
System.out.println(obj.toString());
}
}
*/
内部类作为private成员
public class M2 {
public static void main(String args[])
{
Abs a = new Outer().getObject();//多态。
a.run();
}
}
abstract class Abs
{
public abstract void run();
}
class Outer
{
int x=123;
private class Inner extends Abs
{
public void run() {
System.out.println("x="+x);
}
}
public Inner getObject()
{
return new Inner();
}
public void run()
{
new Inner().run();
}
}
匿名内部类
一个抽象方法
abstract class AnonymousClassDemo{
abstract void show();
}
class Outer{
int num=3;
public void method(){
new AnonymousClassDemo(){
void show(){
System.out.println("adf");
}
}.show();
}
}
public class TestAnonymousClass{
public static void main(String[] args){
Outer out = new Outer();
out.method();
}
}
两个抽象方法
interface Inter{
void show1();
void show2();
}
class Outer{
int num=4;
public void method(){
Inter inter=new Inter(){
public void show1(){System.out.println("abc");}
public void show2(){System.out.println("def");}
};
inter.show1();
inter.show2();
}
}
public class TestAnonymousClass{
public static void main(String[] args){
Outer out = new Outer();
out.method();
}
}
return一个匿名内部类
interface Inter{
public void show();
}
class Outer{
public static Inter method(){
return new Inter(){
public void show(){
System.out.println("show");
}
};
}
}
public class TestAnonymousClass{
public static void main(String[] args){
Outer.method().show();
//new Outer().method().show();
}
}
编译失败的小例子
interface Inter{
public void show();
}
class Outer{
public void method(){
/*程序1*/
new Object(){
public void show(){
System.out.println("show");
}
}.show();//编译成功
/*程序2*/
Object obj1=new Object(){//在程序1的基础上,为匿名内部类new Object()加了名字obj1
public void show(){
System.out.println("show");
}
};
//obj1.show();//在这里编译失败,因为obj1是Object类的对象,Object类里没有show()方法
/*程序3*/
Object obj2=new Inter(){//改进程序2,创建匿名内部类(接口)Inter,并向上转型为Object类型
public void show(){
System.out.println("show");
}
};
Inter inter=(Inter)obj2;//向下转型为Inter类型
inter.show();//Inter类里有show()方法,可以编译通过
/*程序4*/
Inter in=new Inter(){//改进程序3,不再有繁杂的转型,创建匿名内部类Inter
public void show(){
System.out.println("show");
}
};
in.show(); //Inter里有show()方法,可以编译通过
}
}
public class TestAnonymousClass{
public static void main(String[] args){
new Outer().method();
}
}
疑问
class Outer
{
Object obj;
public void method()
{
final int y = 12345;
class Inner
{
public String toString()//overloaded
{
return "@java.lang.String[ "+y+" ]";
}
}
obj = new Inner();
}
public void function()
{
System.out.println(obj.toString());
}
}
public class TestAnonymousClass{
public static void main(String[] args)
{
Outer out=new Outer();
out.method();//问题出在这句。当时脑子短路。
/*
问:注释掉第二句,有Outer$1Inner.class文件产生。但是会报错。
老师答:在java里 所有内部类都是等同于外部类的,所以你编译后 自然会产生内部类的class
问:没有这句,就会编译错误:Exception in thread "main" java.lang.NullPointerException
老师答:空指针一般都是仅有栈 没有堆,还想用堆的东西,就错了
我:哦对,我才发现。不执行method()就没有这句赋值:obj = new Inner() 自然就指空了....
*/
out.function();
}
}