------------恢复内容开始------------
1.成员内部类
(1)格式
class Out{ class In{ } }
(2)特点
a. 访问内部类的属性和方法时的步骤:
* 1.首先是实例化外部类的对象
* 2.接着通过外部对象实例化内部对象
1 package NeiBuLei; 2 3 /* 4 * 成员内部类 5 */ 6 public class Out { 7 8 private String outName="Out"; 9 int value=12138; 10 public void outMethod(){ 11 System.out.println("+++++++++执行外部类的方法++++++++++"); 12 } 13 14 //内部类 15 class In{ 16 String inName="In"; 17 18 public void inMethod(){ 19 System.out.println("----------执行内部类的方法------------"); 20 } 21 22 } 23 24 public static void main(String[] args){ 25 26 /* 27 * 访问内部类的属性和方法时的步骤: 28 * 1.首先是实例化外部类的对象 29 * 2.接着通过外部对象实例化内部对象 30 */ 31 Out o=new Out(); 32 In i=o.new In(); 33 34 o.outMethod(); 35 i.inMethod(); 36 37 } 38 }
运行结果:
+++++++++执行外部类的方法++++++++++
----------执行内部类的方法------------
b. 成员内部类可以无条件访问外部类的属性和方法,但是外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法
外部类访问内部类的属性:
1 package NeiBuLei; 2 3 /* 4 * 成员内部类 5 */ 6 public class Out { 7 8 private String outName="Out"; 9 10 public void eat(){ 11 In i=new In();//首先实例化一个内部类的对象 12 System.out.println("访问内部类的属性----->"+i.inName);//访问内部类的属性 13 //调用内部类的方法 14 i.run(); 15 } 16 17 18 //内部类 19 class In{ 20 String inName="In"; 21 22 public void run(){ 23 System.out.println("访问外部类的属性+++++++>"+outName); //内部类可以无条件的访问外部类的属性,即使外部类的属性被private修饰 24 } 25 26 } 27 28 public static void main(String[] args){ 29 30 Out o=new Out(); 31 o.eat(); 32 33 } 34 }
运行结果:
注:内部类中不能使用:public static void main(String[] args)
c.如果成员内部类的属性或者方法与外部类的同名,将导致外部类的这些属性与方法在内部类被隐藏,也可按照该格式调用,外部类.this.属性/方法。
1 package NeiBuLei; 2 3 /* 4 * 成员内部类 5 */ 6 public class Out { 7 8 private String outName="Out"; 9 int value=12138; 10 public void outMethod(){ 11 System.out.println("+++++++++执行外部类的方法++++++++++"); 12 } 13 14 public void run(){ 15 System.out.println("+++++++++>外部类的run方法"); 16 } 17 18 //内部类 19 class In{ 20 String inName="In"; 21 int value=1; 22 public void inMethod(){ 23 System.out.println("----------执行内部类的方法------------"); 24 } 25 26 public void run(){ 27 System.out.println("----------->内部类的run方法"); 28 System.out.println(value); 29 System.out.println(Out.this.value); //如果外部类的属性在内部类中被覆盖,可以通过:外部类名.this.属性名 的方式,访问在内部类中被覆盖的外部类的属性 30 System.out.println(outName); //如果外部类的属性在内部类中没有被覆盖,则可以直接访问。 31 } 32 33 } 34 35 public static void main(String[] args){ 36 37 /* 38 * 访问内部类的属性和方法时的步骤: 39 * 1.首先是实例化外部类的对象 40 * 2.接着通过外部对象实例化内部对象 41 */ 42 Out o=new Out(); 43 In i=o.new In(); 44 45 //o.outMethod(); 46 //i.inMethod(); 47 48 o.run(); 49 i.run(); 50 51 52 } 53 }
运行结果:
d.内部成员类的访问权限
成员内部类前可加上四种访问修饰符。
private:仅外部类可访问。
protected:同包下或继承类可访问。
default:同包下可访问。
public:所有类可访问。
2.局部内部类
局部内部类存在于方法中,不能用public或private进行声明,它的作用域被限定在声明这个局部类的块中,即只能在这个方法中使用
局部内部类的优势是:
(1)可以对外部世界完全地隐藏起来,除了类所在的方法外,其余代码都不能访问它
(2)相比于其他内部类,局部内部类不仅能够访问包含它的外部类,而且还能访问包含它的方法中的局部变量,但是这些局部变量必须被finalx修饰,即这些变量一旦被赋值,就绝不会改变。
注:关于访问方法中的属性必须被final修饰这一点,之前的版本确实需要被final修饰,但是新的版本中属性不用被final修饰,即可访问
1 package NeiBuLeiTest2; 2 3 4 /* 5 * 局部内部类 6 */ 7 public class Outter { 8 9 String outName="外部类的属性"; 10 11 public void outMethod(){ 12 System.out.println("++++++++=外部类方法++++++++"); 13 } 14 15 16 public void outRun(){ 17 System.out.println("+++++++++外部类的run方法++++++++"); 18 19 String outRunName="外部类run方法中的属性,没有被final修饰"; 20 21 final String outRunNameWithFinal="包含局部内部类的run方法中被final修饰的属性"; 22 23 class Inner{ 24 String inName="局部内部类中的属性"; 25 public void inMethod(){ 26 System.out.println("---------局部内部类方法----------"); 27 System.out.println("访问外部类的属性+++++++++>"+outName); 28 29 System.out.println("访问包含局部内部类方法中的没有被final修饰的属性---------->"+outRunName); 30 31 System.out.println("访问包含局部内部类方法中的被final修饰的属性---------->"+outRunNameWithFinal); 32 33 System.out.println("访问局部内部类的属性---------->"+inName); 34 35 } 36 37 38 public void inRun(){ 39 System.out.println("----------内部类的run方法-----------"); 40 } 41 } 42 43 Inner i=new Inner(); 44 i.inMethod(); 45 46 } 47 48 public static void main(String[] args){ 49 Outter o=new Outter(); 50 51 o.outRun(); 52 } 53 54 }
运行结果:
3.匿名内部类
3.1 什么是匿名内部类?
《Java程序设计基础(第五版)》中对匿名内部类的描述:“所谓匿名内部类,是指可以利用内部类创建没有名称的对象,它一步完成了声明内部类和创建该类的一个对象,并利用该对象访问到类里面的成员”。
匿名内部类可以使代码更加简洁,可以在定义一个类的同时对其进行实例化。它与局部类很相似,不同的是它没有类名,如果某个局部类只需要用一次,那么就可以使用匿名内部类。比如说,你想实现一个接口,我们都知道,接口不能直接实例化,得创建一个类去继承这个接口,然后再实现接口中的方法,但是,这个新创建出来的类只是起到了一个实现接口的作用,并无其它作用,这样会使代码显得繁琐,这个时候可以使用匿名内部类的方法来实现接口的继承。
注:因为匿名内部类没有名字,所以它没有构造方法
1 package NiMingNeiBuLei; 2 3 public class Out{ 4 5 public void run(){ 6 7 /* 8 * 匿名内部类 9 * 想要继承Test接口并实现其eat()、sleep()方法,有两种方法 10 */ 11 12 13 //法一:首先创建一个类In并继承Test接口,接着实例化一对象,通过对象调用方法 14 15 class In implements Test{ 16 public void eat(){ 17 System.out.println("++++++内部类吃饭++++++"); 18 } 19 20 public void sleep(){ 21 System.out.println("++++++内部类睡觉++++++"); 22 } 23 24 } 25 26 27 In i=new In(); 28 i.eat(); 29 i.sleep(); 30 31 32 //法二:采用匿名内部类的方法: 33 //注:这里的new必须是接口名,不能随便写 34 Test n=new Test(){ 35 public void eat(){ 36 System.out.println("------》匿名内部类吃饭《------"); 37 } 38 39 public void sleep(){ 40 System.out.println("------》匿名内部类睡觉《------"); 41 } 42 }; 43 44 n.eat(); 45 n.sleep(); 46 } 47 48 public static void main(String[] args){ 49 Out o=new Out(); 50 o.run(); 51 } 52 53 }
4. 静态内部类
有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象,这个时候,可以将内部类声明为static,以取消产生的使用。内部静态类也称作嵌套类。
1 package NeiBuLeiTest2; 2 3 /** 4 * 外部类、内部类定义 5 */ 6 public class Outer { 7 8 private int outerVariable = 1; 9 10 /** 11 * 外部类定义的属性(重名) 12 */ 13 private int commonVariable = 2; 14 15 private static int outerStaticVariable = 3; 16 17 static { 18 System.out.println("+++++++++>外部类Outer的静态块<+++++++++"); 19 } 20 21 /** 22 * 成员方法 23 */ 24 public void outerMothod() { 25 System.out.println("+++++++++>外部类的outerMethod方法<+++++++++"); 26 } 27 28 /* 29 * 静态方法 30 */ 31 public static void outerStaticMethod() { 32 System.out.println("+++++++++++>外部类的outerStaticMethod静态方法<++++++++++++++"); 33 } 34 35 36 /** 37 * 静态内部类 38 */ 39 public static class Inner { 40 /** 41 * 成员信息 42 */ 43 private int innerVariable = 10; 44 private int commonVariable = 20; 45 46 static { 47 System.out.println("---------->内部静态类Inner的静态块<------------"); 48 } 49 50 private static int innerStaticVariable = 30; 51 52 /** 53 * 成员方法 54 */ 55 public void innerShow() { 56 System.out.println("innerVariable:" + innerVariable); 57 System.out.println("外部类和内部类都有的公共属性,内部覆盖外部,commonVariable:" + commonVariable); 58 System.out.println("outerStaticVariable:"+outerStaticVariable); 59 outerStaticMethod(); 60 } 61 62 /** 63 * 静态方法 64 */ 65 public static void innerStaticShow() { 66 //被调用时会先加载Outer类 67 // outerStaticMethod(); 68 System.out.println("----------》静态内部类的静态方法《-------------"); 69 } 70 } 71 72 73 }
1 package NeiBuLeiTest2; 2 3 public class Demo { 4 public static void main(String[] args) { 5 //访问静态内部类的静态方法,Inner类被加载,此时外部类未被加载,独立存在,不依赖于外围类。 6 Outer.Inner.innerStaticShow(); 7 //访问静态内部类的成员方法 8 Outer.Inner oi = new Outer.Inner(); 9 oi.innerShow(); 10 } 11 } 12 13 14 15
运行结果:
原文:https://www.cnblogs.com/Leeyoung888/p/14199687.html