内部类
Posted zwb1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部类相关的知识,希望对你有一定的参考价值。
定义:可以将一个类的定义放在另一个类的内部定义,这就是内部类。
外部类可以有一个方法,用来返回一个指向一个内部类对象的引用,如下所示。需要注意的是,该方法必须是非静态方法,而且需要具体指明该对象的类型,即 外部类.内部类。如下所示
1 public class OuterClass { 2 3 class InnerClass{ 4 //这是一个内部类 5 void sayHello(){ 6 System.out.println("hello"); 7 } 8 } 9 10 public InnerClass getInner(){ 11 return new InnerClass(); 12 } 13 }
运行:
1 public class Test { 2 public static void main(String[] args){ 3 OuterClass outerClass = new OuterClass(); 4 OuterClass.InnerClass inner = outerClass.getInner(); 5 inner.sayHello(); 6 }
结果:hello
除了通过在外部类中直接new的方式创建内部类对象,还可以通过外部类对象来创建。
1 OuterClass outerClass = new OuterClass(); 2 OuterClass.InnerClass innerClass = outerClass.new InnerClass();
在内部类中,也可以用过外部类.this的方式返回一个外部类的引用
1 class InnerClass{ 2 //这是一个内部类,即使他没有属性 3 void sayHello(){ 4 System.out.println("hello "); 5 } 6 7 OuterClass getOut(){ 8 return OuterClass.this; 9 } 10 }
《java》编程思想:在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地连接到创建它的外部类对象上。但是,如果你创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。
如果内部类仅此而已,那么和普通的类又有什么区别呢?下面列举内部类的其他用途
1、内部类可以访问外部类的所有元素。
修改OuterClass,新增private name字段,并在内部类中使用
1 public class OuterClass { 2 3 private String name; 4 OuterClass(String name){ 5 this.name = name; 6 } 7 8 class InnerClass{ 9 //这是一个内部类,即使他没有属性 10 void sayHello(){ 11 System.out.println("hello"+name); 12 } 13 } 14 15 public InnerClass getInner(){ 16 return new InnerClass(); 17 } 18 }
运行:
public class Test { public static void main(String[] args) throws IOException { OuterClass outerClass = new OuterClass("zhangsan"); OuterClass.InnerClass inner = outerClass.getInner(); inner.sayHello(); }
结果: hello zhangsan
为什么内部类可以访问外部类的所有元素?
《java编程思想》:当某个外围类的对象创建了一个内部类的对象时,此内部类对象必定会秘密捕获一个指向那个外围类对象的引用。然后,在你访问此外围类的成员时,就是用那个引用来选择外围类的成员。幸运的是,编译器会帮你处理所有的细节。
2、内部类可以向上转型
内部类可以向上转型为其基类,这是,我们所得到的只是一个指向其基类或者是接口的引用,能够隐藏其实现的细节。
需要一个接口:
1 public interface IService { 2 void doSomething(); 3 }
外部类与内部类代码:
1 public class OuterClass { 2 3 private class InnerClass implements IService{ 4 public void doSomething() { 5 System.out.println("inner class"); 6 } 7 } 8 9 public IService getInner(){ 10 return new InnerClass(); 11 } 12 }
运行:
1 public class Test { 2 public static void main(String[] args) throws IOException { 3 OuterClass outerClass = new OuterClass(); 4 IService inner = outerClass.getInner(); 5 inner.doSomething(); 6 }
结果:inner class
3、可以在一个方法中定义内部类。称为局部内部类
修改上面的getInner方法如下:
1 public IService getInner(){ 2 class InnerClass implements IService{ 3 public void doSomething() { 4 System.out.println("inner class"); 5 } 6 } 7 return new InnerClass(); 8 }
此时,InnerClass是作为getInner方法的一部分,而不是OuterClass的一部分,所以,只能在getInner方法中才能访问InnerClass
4、匿名内部类
对于getInner方法,可以直接写成如下形式:
1 public IService getInner(){ 2 return new IService() { 3 public void doSomething() { 4 System.out.println("inner class"); 5 } 6 }; 7 }
可以看到,这个方法将返回值的生成和类的定义结合在了一起,而且,这个类没有名字。
5、嵌套类
我们知道,要创建内部类必须要有外部类的对象,但是,如果将内部类声明为static,就可以不通过外部类的对象来创建内部类,同时,也不能访问外部类的非静态元素。
补充:普通内部类不能有static字段和static方法,而且不能包含嵌套类,而嵌套类可以包含这些所有东西。
普通内部类:可以访问外部类的所有成员,自己不能有static
嵌套类:只能访问外部类的static,自己可以有static也可以有别的
6、接口内部的类
如果你想要创建某些公共代码,使得它可以被某个接口的不同实现所公用,就可以在接口内部定义嵌套类,在接口中定义的类都是public和static的
1 public interface IService { 2 void doSomething(); 3 class MyService implements IService{ 4 public void doSomething() { 5 System.out.println("myservice"); 6 } 7 } 8 }
在IService接口的实现类中可以调用MyService
1 private static class InnerClass implements IService{ 2 public void doSomething() { 3 MyService myService = new MyService(); 4 myService.doSomething(); 5 } 6 }
运行:
1 OuterClass outerClass = new OuterClass(); 2 IService inner = outerClass.getInner(); 3 inner.doSomething();
结果:myservice
为什么要使用内部类?
每一个内部类都能独立的继承一个其他的类,或是接口的实现,无论外围类是否已经继承了某个实现,对内部类都没有影响。由此,可以利用内部类,来实现java的多重继承
以上是关于内部类的主要内容,如果未能解决你的问题,请参考以下文章