疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java成员内部类、匿名内部类


 

   

  内部类:

  一个类中定义另外一个类,这样的类叫内部类。

  内部类的文件名:外部类名$内部类名.class

  内部类分两种:

  1.成员内部类

  如何访问成员内部类:

  方式1:外部类中定义一个方法来创建内部类对象,再通过对象进行访问。

  方式2:可以直接在其他类中直接创建内部类这个对象,通过对象访问。用点语。

  格式:外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

  内部类使用的注意事项:

  1.如果外部类和内部类中有同名的成员变量,那么在内部类中java虚拟机默认访问内部类中的成员变量,可以通过格式: 外部类名.this.变量名。

  2.如果内部类中的成员被private 修饰了,那么只能用方式1 来访问内部类的成员。

  3.内部类中有变量被 static 修饰了,那么这个类也必须是一个静态的类。

  内部类使用的好处:

  内部类中是可以直接访问外部类的所有成员。实际上还是外部类自己调用的。外部类拥有内部类。

  一般什么时候使用内部类:

  我们在描述一个A对象,发现A对象中又需要有一个对象B,对象B很复杂,B对象又想访问A中的数据。这个时候用内部类来描述B对象就更方便了。

  又比如说:人有心脏,人也有血液。人是一个类,心脏是一个类,血液也是一个类。 那么心脏想访问血液的话就很麻烦。

  复制代码

  1 package study;

  2

  3 class Outer {

  4

  5 int i = 10;//自带的成员变量 外部类

  6

  7 //定义一个内部类

  8 //成员内部类

  9 class Inner{

  10

  11 int i = 20;//内部类的变量

  12

  13 public void print() {

  14 System.out.println("这个是内部类"+i);//打印的是20

  15 System.out.println("这个是内部类"+Outer.this.i);//访问的是外部类的属性

  16 }

  17 }

  18 //创建一个方法来创建内部类对象(方式1)

  19 /* public void instantce(){

  20 //创建内部类对象

  21 Inner inner = new Inner();

  22 inner.print();

  23 }*/

  24 }

  25 //其他类

  26 public class star {

  27 public static void main(String[] args) {

  28 /* //在其他类中访问内部类(方式1)

  29 Outer outer= new Outer();

  30 outer.instantce();*/

  31

  32 //其他类中直接访问:(方式2)

  33 Outer.Inner inner = new Outer().new Inner();

  34 inner.print();

  35

  36 }

  37 }

  复制代码

  2.局部内部类

  局部内部类:在类方法中定义的类,这样的一个类叫局部内部类。

  局部内部类只能通过第一种方式来访问。

  局部内部类使用注意点:

  如果局部内部类访问了方法中的局部变量,方法中的局部内部类必须用final来修饰。

  复制代码

  1 class Outer{

  2 String name = "外部类的name";

  3 int i = 20;

  4

  5 public void test() {

  6

  7 final int i = 30;//局部变量 出了这个方法就消失。

  8 //为什么要用final来修饰?

  9 /*test方法执行完,变量i 立马从内存中消失,而inner对象在方法执行完之后,没有消失的,这里再使用i就好比把i的生命周期延迟了,与局部变量的定义不符。

  10 *所以用final修饰,相当于把i设置了一个复制品给test方法使用,真实的i已经消失。

  11 * */

  12

  13 //局部内部类

  14 class Inner{

  15 public void print(){

  16 /*int i = 10; 注销之后研究拿到30这个i*/

  17 System.out.println("这个是局部内部类的方法"+i);//打印的是10

  18 }

  19 }

  20 //创建局部对象

  21 Inner inner = new Inner();//test走完,这个对象可能还存在(它是由java虚拟机决定消除的,不知道是什么时候),存在的话相当于给 i 的生命周期延迟了。

  22 inner.print();

  23 }

  24 }

  25

  26 public class Star {

  27

  28 public static void main(String[] args) {

  29 //在其他类中访问局部内部类

  30 Outer out = new Outer();

  31 out.test();

  32

  33 //下面是错误的写法

  34 /*Outer.Inner inner = new Outer().new Inner();

  35 inner.print();*/

  36 }

  37 }

  复制代码

  匿名的内部类(没有类名的类)

  好处:简化书写

  匿名内部类使用前提:外部类必须有继承或者实现关系。

  因为它没有名字,它实际创建出来是靠父类来创建的,以多态表现出来的。所以要继承或实现关系。

  它的实现实际以多态的形式表现的所以需要满足上面的条件。

  匿名内部类一般用于实际参数的传递。(和匿名对象用法一样)

  复制代码

  abstract class Animal{

  public abstract void run();

  public abstract void sleep();

  }

  //外部类

  //在Outer里面创建一个Dog的内部类

  class Outer{

  //不用匿名

  /*class Dog extends Animal{

  public void run() {

  System.out.println("狗在跑");

  }

  public void sleep() {

  System.out.println("狗在睡觉");

  }

  }*/

  public void print(){

  //Dog d = new Dog();

  //d.run();

  //匿名的Dog(通过父类来完成创建)

  //匿名内部类:只是没有名字,其它的和普通的类没什么不一样

  Animal a = new Animal(){//不是父类创建对象 匿名内部类(子类)

  //具体实现

  public void run(){

  System.out.println("狗在跑");

  };

  public void sleep(){

  System.out.println("狗在睡觉");

  };

  };

  a.run();

  a.sleep();

  };

  }

  public class Star {

  public static void main(String[] args) {

  Outer out = new Outer();

  out.print();

  }

  }

  复制代码