2018/01/09JAVA 基础 / 接口与继承 / JAVA的4种内部类详解

时间:2023-02-15 17:46:07

  所谓内部类,就是在一个类的内部又设计了一个类。内部类可分为四种:非静态内部类 、静态内部类 、匿名类 、本地类。

一、非静态内部类

1)代码案例 :

 1 package charactor;
 2  
 3 public class Hero {
 4     private String name; // 姓名
 5  
 6     float hp; // 血量
 7  
 8     float armor; // 护甲
 9  
10     int moveSpeed; // 移动速度
11  
12     // 非静态内部类,只有一个外部类对象存在的时候,才有意义
13     // 战斗成绩只有在一个英雄对象存在的时候才有意义
14     class BattleScore {
15         int kill;
16         int die;
17         int assit;
18  
19         public void legendary() {
20             if (kill >= 8)
21                 System.out.println(name + "超神!");
22             else
23                 System.out.println(name + "尚未超神!");
24         }
25     }
26  
27     public static void main(String[] args) {
28         Hero garen = new Hero();
29         garen.name = "盖伦";
30         // 实例化内部类
31         // BattleScore对象只有在一个英雄对象存在的时候才有意义
32         // 所以其实例化必须建立在一个外部类对象的基础之上
33         BattleScore score = garen.new BattleScore();
34         score.kill = 9;
35         score.legendary();
36     }
37  
38 }

 

2)特点归纳:

  • 非静态内部类的声明方式:class + 类名
  • 非静态内部类可以直接在一个类里面定义,即非静态/静态内部类必须声明在成员的位置,即与属性和方法平等的位置
  • 非静态内部类只有在外在类的对象存在的时候才有意义。即调用非静态内部类成员需要实例化,其方式为:内部类 引用名 = new 外部类().new 内部类()
  • 非静态内部类可以直接访问外部类的成员,无论是静态还是非静态。

二、静态内部类

1)代码案例 :

 1 package charactor;
 2   
 3 public class Hero {
 4     public String name;
 5     protected float hp;
 6   
 7     private static void battleWin(){
 8         System.out.println("battle win");
 9     }
10      
11     //敌方的水晶
12     static class EnemyCrystal{
13         int hp=5000;
14          
15         //如果水晶的血量为0,则宣布胜利
16         public void checkIfVictory(){
17             if(hp==0){
18                 Hero.battleWin();
19                  
20                 //静态内部类不能直接访问外部类的对象属性
21                 System.out.println(name + " win this game");
22             }
23         }
24     }
25      
26     public static void main(String[] args) {
27         //实例化静态内部类
28         Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
29         crystal.checkIfVictory();
30     }
31   
32 }

2)特点归纳:

  • 静态内部类的声明方式:static + class + 类名
  • 静态内部类必须声明在成员的位置,即与属性和方法平等的位置
  • 静态内部类无需外在类的对象存在。但调用静态内部类成员亦需实例化,其方式为:内部类 引用名 = new 外部类.new 内部类()
  • 静态内部类可以直接访问外部类的非静态成员,但不能直接访问静态成员。 

三、匿名类

1)代码案例 :

 1 package charactor;
 2    
 3 public abstract class Hero {
 4     String name; //姓名
 5           
 6     float hp; //血量
 7           
 8     float armor; //护甲
 9           
10     int moveSpeed; //移动速度
11       
12     public abstract void attack();
13       
14     public static void main(String[] args) {
15           
16         ADHero adh=new ADHero();
17         //通过打印adh,可以看到adh这个对象属于ADHero类
18         adh.attack();
19         System.out.println(adh);
20           
21         Hero h = new Hero(){
22             //当场实现attack方法
23             public void attack() {
24                 System.out.println("新的进攻手段");
25             }
26         };
27         h.attack();
28         //通过打印h,可以看到h这个对象属于Hero$1这么一个系统自动分配的类名
29           
30         System.out.println(h);
31     }
32       
33 }

 

2)特点归纳:

  • 为了直接在抽象类中实现抽象方法而不建立子类,就可以使用匿名类。故,匿名类的功能就是直接实现抽象方法;
  • 匿名类在实例化的同时实现抽象方法,匿名类不需要显式声明,直接实例化,故:匿名类没有显示命名,其名字由系统分配;
  • 匿名类实例化直接声明在代码块里【主方法内,for循环里,静态方法内】。实例化格式为:外部类 引用 = new 外部类{ 实现抽象方法};

四、本地类

1)代码案例 :

  

 1 package charactor;
 2    
 3 public abstract class Hero {
 4     String name; //姓名
 5           
 6     float hp; //血量
 7           
 8     float armor; //护甲
 9           
10     int moveSpeed; //移动速度
11       
12     public abstract void attack();
13       
14     public static void main(String[] args) {
15           
16         //与匿名类的区别在于,本地类有了自定义的类名
17         class SomeHero extends Hero{
18             public void attack() {
19                 System.out.println( name+ " 新的进攻手段");
20             }
21         }
22          
23         SomeHero h  =new SomeHero();
24         h.name ="地卜师";
25         h.attack();
26     }
27       
28 }

 

2)特点归纳:

  • 与匿名类的区别在于,本地类有自定义的类名,
  • 本地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方
  • 本地类的声明方式为:class+类名+extends+外部类
  • 本地类需要实例化,方式:本地类 引用 = new 本地类();
  • 由于本地类是继承了外部类,故:本地类具有子类的所有特点