内部类分别有成员内部类、局部内部类、匿名内部类、静态内部类,接下来将分别介绍。java
public class Demo1 { innerclass in=new innerclass(); //在成员内部类所在的外类中实例化成员内部类 public void outf() { in.inf(); //由于in是成员内部类的实例化,因此才能够调用 } class innerclass{//成员内部类 int y=0; public innerclass() {//成员内部类的构造方法 } public void inf() { System.out.println("内部类方法y="+y); } } public static void main(String[] args) { Demo1 iDemo1=new Demo1(); iDemo1.outf(); Demo1.innerclass j= iDemo1.new innerclass(); //非外部类位置成员内部类实例化的方法(即首先要实例化一个外部类) Demo1.innerclass k=new Demo1().new innerclass(); //实例化外部类和构造内部类一块儿写 j.inf(); } }
public class Demo2 { public outinterface action(String x) {//要把这个类返回出去,就须要经过接口,由于内部类在外部做用域中不存在 class innerclass2 implements outinterface{ public innerclass2(String s) { s = x; System.out.println(s); } } return new innerclass2("do"); } public static void main(String[] args) { Demo2 demo2=new Demo2(); demo2.action("局部内部类"); } } interface outinterface{ //专门用来给局部内部类作向上转型的父接口的操做 }
局部内部类只能在所在的方法体做用域内进行实例化,而若是要在所在方法体返回该类,就要经过接口向上转型的操做。(如同上处代码)
2. 做用
在某些状况下,某些业务逻辑须要临时处理,这些业务逻辑只在这里使用又能够封装成一个类的话,而又不必从新建个文件,因此能够这写一个局部内部类来处理。而后,在个人记忆中,java代理模式中有用到局部内部类,在方法中直接实现接口,返回代理对象,简单而又方便。安全
静态字段的内部类,和静态方法并列。学习
public class Demo3 { static int x=100; static class innerclass3 { void action() { x=1; //x必须是静态字段 } public static void main(String[] args) { System.out.println("我是静态内部类"); } } }
//代码示例一 public class Demo4 { public Outinterface2 action() { //return new innerclass2(); ① return new Outinterface2() { //② private int i = 0; public int getvalue() { return i; } }; } } interface Outinterface2 { } class innerclass2 implements Outinterface2{//① private int i = 0; public int getvalue() { return i; } }
//代码示例二 interface Inner { public abstract void show(); } class Outer { public void method(){ new Inner() { public void show() { System.out.println("HelloWorld"); } }.show(); } } class Test { public static void main(String[] args) { Outer o = new Outer(); o.method(); } } //若是匿名内部类中有多个方法又该如何调用呢? Inter i = new Inner() { //多态,由于new Inner(){}表明的是接口的子类对象 public void show() { System.out.println("HelloWorld"); } };
上述代码①和②的做用是相同的。由此也能够解释一下匿名内部类的做用。测试
做为一个类的编写者,咱们很显然须要对这个类的使用访问者的访问权限作出必定的限制,咱们须要将一些咱们不肯意让别人看到的操做隐藏起来,若是咱们的内部类不想轻易被任何人访问,能够选择使用private修饰内部类,这样咱们就没法经过建立对象的方法来访问,想要访问只须要在外部类中定义一个public修饰的方法,间接调用。代理
public interface Demo { void show(); } class Outer { private class test implements Demo { public void show() { System.out.println("密码备份文件"); } } public Demo getInner() { return new test(); } }
咱们以前的学习知道,java是不能够实现多继承的,一次只能继承一个类,咱们学习接口的时候,有提到能够用接口来实现多继承的效果,即一个接口有多个实现,可是这里也是有一点弊端的,那就是,一旦实现一个接口就必须实现里面的全部方法,有时候就会出现一些累赘,可是使用内部类能够很好的解决这些问题。调试
public class Demo1 { public String name() { return "BWH_Steven"; } } public class Demo2 { public String email() { return "xxx.@163.com"; } } public class MyDemo { private class test1 extends Demo1 { public String name() { return super.name(); } } private class test2 extends Demo2 { public String email() { return super.email(); } } public String name() { return new test1().name(); } public String email() { return new test2().email(); } public static void main(String args[]) { MyDemo md = new MyDemo(); System.out.println("个人姓名:" + md.name()); System.out.println("个人邮箱:" + md.email()); } }
咱们编写了两个待继承的类Demo1和Demo2,在MyDemo类中书写了两个内部类,test1和test2二者分别继承了Demo1和Demo2类,这样MyDemo中就间接的实现了多继承。code
咱们用通俗讲解就是说在Java中,一般就是编写一个接口,而后你来实现这个接口,而后把这个接口的一个对象做以参数的形式传到另外一个程序方法中, 而后经过接口调用你的方法,匿名内部类就能够很好的展示了这一种回调功能。对象
public interface Demo { void demoMethod(); } public class MyDemo{ public test(Demo demo){ System.out.println("test method"); } public static void main(String[] args) { MyDemo md = new MyDemo(); //这里咱们使用匿名内部类的方式将接口对象做为参数传递到test方法中去了 md.test(new Demo){ public void demoMethod(){ System.out.println("具体实现接口") } } } }
编写一个接口Demo继承
public interface Demo { void test(); }
编写一个类 MyDemo接口
public class MyDemo { public void test() { System.out.println("父类的test方法"); } }
二者的方法名字都是test,下面编写一个测试类;
public class DemoTest extends MyDemo implements Demo { public void test() { } }
这样的话我就有点懵了,这样如何区分这个方法是接口的仍是继承的,因此咱们使用内部类解决这个问题
public class DemoTest extends MyDemo { private class inner implements Demo { public void test() { System.out.println("接口的test方法"); } } public Demo getIn() { return new inner(); } public static void main(String[] args) { //调用接口而来的test()方法 DemoTest dt = new DemoTest(); Demo d = dt.getIn(); d.test(); //调用继承而来的test()方法 dt.test(); } } //运行结果 接口的test方法 父类的test方法