每日学习-Java基础(十)接口和继承10(内部类)

一、内部类

内部类

// 内部类有四种类型
// 1-非静态内部类
// 2-静态内部类
// 3-匿名类
// 4-本地类

1、非静态内部类

package ia10_innerClass;

public class Hero {
	private String name;
	protected float hp;
	protected int armor;
	protected int moveSpeed;

	// 非静态内部类
	class BattleScore {
		private int kill;

		public void legendary() {
			if (kill >= 8) {
				System.out.println(name + "已超神!");
			} else {
				System.out.println(name + "还未超神!");
			}
		}

		public int getKill() {
			kill = 10;
			return kill;
		}
	}

	public static void main(String[] args) {
		Hero h = new Hero();
		h.name = "garen";
		// --实例化内部类
		// 实例化内部类必须建立在外部类实例的基础上。
		// 非静态内部类可以访问外部类,private修饰也可访问。
		// BattleScore必须建立在有一个Hero的基础上,没有英雄,何来战绩?
		// --访问方式
		// new Hero().new BattleWin();
		// new OuterClass().new InnerClass();
		BattleScore bW = h.new BattleScore();
		bW.kill = 9;
		bW.legendary();
		System.out.println(new Hero().new BattleScore().getKill());
	}
}

运行结果:
在这里插入图片描述
2、静态内部类

package ia10_innerClass2;

public class Hero {
	public String name; // 英雄名称
	protected float hp; // 血量

	private static void battleWin() {
		System.out.println("hero battle win");
	}

	// 静态内部类 static修饰
	static class EnemyCrystal {
		int hp = 5000;

		public void CheckIfVictory() {
			if (hp == 0) {
				Hero.battleWin();
				// System.out.println(name + "win!"); // 不能访问name
			}
		}
	}

	public static void main(String[] args) {
		// --静态内部类
		// 静态内部类实例化,不需外部类的实例。
		// 因为静态内部类没有外部类实例,所有静态内部类不能访问外部类。
		// --访问方法
		// new 外部类.内部类();
		// 实例化静态内部类
		Hero.EnemyCrystal ec = new Hero.EnemyCrystal();
		ec.hp = 0;
		ec.CheckIfVictory();
	}
}

运行结果:
在这里插入图片描述
3、匿名类

package ia10_innerClass3;

public abstract class Hero {
	protected String name;
	protected float hp;
	protected int armor;
	protected int moveSpeed;
	
	public abstract void attack();
	
	public static void main(String[] args) {
		// 匿名类
		// 声明一个类时实例化
		// 使用接口/抽象类,必须有子类实现
		// 直接实例化,并实现抽象方法,是一个新的类,但没有名字,即匿名类
		Hero h = new Hero() {
			@Override
			public void attack() {
				// TODO Auto-generated method stub
				System.out.println("进行攻击");
			}
		};
		h.attack();
		System.out.println(h); // Hero$1是系统自动分配的类名
		
		ADHero ad = new ADHero();
		ad.attack();
		System.out.println(ad);
	}
}

运行结果:
在这里插入图片描述
4、本地类

package ia10_innerClass4;

public abstract class Hero {
	protected String name;
	protected float hp;
	protected int armor;
	protected int moveSpeed;
	
	public abstract void attack();
	
	public static void main(String[] args) {
		// 本地类
		// 有名字的匿名类
		class RealHero extends Hero {
			@Override
			public void attack() {
				// TODO Auto-generated method stub
				System.out.println("进行强烈攻击");
			}
		}
		
		RealHero rh = new RealHero();
		rh.attack();
		System.out.println(rh);
	}
}

运行结果:
在这里插入图片描述
匿名类–敲黑板
// 匿名类外部的局部变量必须为final变量

package ia10_innerClass5;

public abstract class Hero {
	protected String name;
	protected float hp;
	protected int armor;
	protected int moveSpeed;
	
	public abstract void attack();
	
	public static void main(String[] args) {
		final int damage = 10;
		Hero h = new Hero() {
			@Override
			public void attack() {
				// TODO Auto-generated method stub
				System.out.printf("进行攻击,造成%d的伤害",damage);
			}
		};
		h.attack();
	}
}

运行结果:
在这里插入图片描述
// 匿名类外部的局部变量为什么是final变量?

package ia10_innerClass6;

public abstract class Hero {
	public abstract void attack();

	public static void main(String[] args) {
		// --在匿名类中使用外部的局部变量damage 必须修饰为final
		// --此处使用 本地类AnonymousHero 模拟匿名类 的隐藏属性机制
		// 事实上的匿名类,会在匿名类里声明一个damage属性,并且使用构造方法初始化该属性的值
		// 在attack中使用的damage,真正使用的是这个内部damage,而非外部damage
		// 假设外部属性不需要声明为final
		// 那么在attack中修改damage的值,就会被暗示为修改了外部变量damage的值
		// 但是他们俩是不同的变量,是不可能修改外部变量damage的
		// 所以为了避免产生误导,外部的damage必须声明为final,"看上去"就不能修改了
		// --区分匿名类外部变量和内部属性
		// 匿名类、本地类中如果外部变量和内部属性同名,在它们内部根本不可能访问到外部变量
		
		int damage = 5;
		class AnonymousHero extends Hero {
			int damage;

			public AnonymousHero(int damage) {
				this.damage = damage;
			}

			@Override
			public void attack() {
				// TODO Auto-generated method stub
				damage = 10; // 内部damage属性,而非外部局部变量
				System.out.printf("进行攻击,造成%d的伤害", this.damage);
			}
		}
		Hero h = new AnonymousHero(damage);
		h.attack();
	}
}

运行结果:
在这里插入图片描述

二、内部类 VS 匿名类

// 匿名类、本地类,声明在代码块中,如方法,for,if等。
// 内部类,声明在和类属性/方法同等位置。

三、练习

创建Item类的匿名类,抽象方法为返回布尔值disposable(),匿名类实现抽象方法。

内部类进阶(网上资料):https://blog.csdn.net/gaoyong_stone/article/details/79556287
我的学习源泉:https://how2j.cn/k/interface-inheritance/interface-inheritance-inner-class/322.html?p=114999
Java自学网站:https://how2j.cn?p=114999

你可能感兴趣的:(Java,java,interface)