2018/01/09JAVA 基础 / 接口与继承 / JAVA的4种内部类详解
所谓内部类,就是在一个类的内部又设计了一个类。内部类可分为四种:非静态内部类 、静态内部类 、匿名类 、本地类。
一、非静态内部类
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 本地类();
- 由于本地类是继承了外部类,故:本地类具有子类的所有特点。