Java内部类

内部类

任务列表

1. 什么内部类?

定义在一个类内部的类,成为内部类。

2.内部类有几种?

内部类:成员内部类(普通内部类),局部内部类,匿名内部类,静态内部类。

3.成员内部类

如何定义一个成员内部类?

需求:

  1. 定义一个Hero类,包含:name, hp, ap
  2. Hero中定义一个内部类,叫BattleScore,包含:kill,die, assit
public class Hero {
	private String name;	//英雄的名字
	private int hp;			//英雄的血量
	private int ap;			//英雄的攻击力
	
	public class BattleScore{//内部类
		private int kill;
		private int die;
		private int assit;
		public int getKill() {
			return kill;
		}
		public void setKill(int kill) {
			this.kill = kill;
		}
		public int getDie() {
			return die;
		}
		public void setDie(int die) {
			this.die = die;
		}
		public int getAssit() {
			return assit;
		}
		public void setAssit(int assit) {
			this.assit = assit;
		}
		public BattleScore() {
			super();
		}
		public BattleScore(int kill, int die, int assit) {
			super();
			this.kill = kill;
			this.die = die;
			this.assit = assit;
		}
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHp() {
		return hp;
	}
	public void setHp(int hp) {
		this.hp = hp;
	}
	public int getAp() {
		return ap;
	}
	public void setAp(int ap) {
		this.ap = ap;
	}
	public Hero() {
		super();
	}
	public Hero(String name, int hp, int ap) {
		super();
		this.name = name;
		this.hp = hp;
		this.ap = ap;
	}
	@Override
	public String toString() {
		return "Hero [name=" + name + ", hp=" + hp + ", ap=" + ap + "]";
	}
	
}

普通内部类的使用

public class TestInnerClass {

	public static void main(String[] args) {
		Hero gailun = new Hero("盖伦", 500, 70);
		Hero.BattleScore bs = gailun.new BattleScore(8, 0, 12);
	}
}

问题:

  1. 成员内部类的访问修饰符可以有哪些?

    public,protected,private以及默认。选哪个取决于需求。

  2. 成员内部类如何创建对象?

    外部类类名.内部类类名 对象名 = 外部类对象.new 内部类类名(实参);

  3. 为什么要有成员内部类?

    有些类只是和某些或某个类有关系,为了更好的组织代码,把一个类定义在了另外一个类里。

内部类可以直接访问外部类的成员(成员方法和成员属性)。

public class Hero {
	private String name;	//英雄的名字
	private int hp;			//英雄的血量
	private int ap;			//英雄的攻击力
	
	public class BattleScore{
		private int kill;
		private int die;
		private int assit;
		
		public void test() {
			System.out.println(name);
		}
		public void test2() {
			name = "亚瑟";
		}
		
		public void test3() {
			setName("怪僧");
		}
		
		public int getKill() {
			return kill;
		}
		public void setKill(int kill) {
			this.kill = kill;
		}
		public int getDie() {
			return die;
		}
		public void setDie(int die) {
			this.die = die;
		}
		public int getAssit() {
			return assit;
		}
		public void setAssit(int assit) {
			this.assit = assit;
		}
		public BattleScore() {
			super();
		}
		public BattleScore(int kill, int die, int assit) {
			super();
			this.kill = kill;
			this.die = die;
			this.assit = assit;
		}
	}
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHp() {
		return hp;
	}
	public void setHp(int hp) {
		this.hp = hp;
	}
	public int getAp() {
		return ap;
	}
	public void setAp(int ap) {
		this.ap = ap;
	}
	public Hero() {
		super();
	}
	public Hero(String name, int hp, int ap) {
		super();
		this.name = name;
		this.hp = hp;
		this.ap = ap;
	}
	@Override
	public String toString() {
		return "Hero [name=" + name + ", hp=" + hp + ", ap=" + ap + "]";
	}
	
}
public class TestInnerClass {

	public static void main(String[] args) {
		Hero gailun = new Hero("盖伦", 500, 70);
		Hero.BattleScore bs = gailun.new BattleScore(8, 0, 12);
		bs.test3();
		bs.test();
	}
}

4.静态内部类

如何定义静态内部类

需求:

  1. 定义一个英雄类Hero,包括:name, hp, ap;
  2. 在Hero类内部定义一个静态内部类敌方水晶类EnemyCrystal, 包括:hp
public class Hero {
	private String name;	//英雄的名字
	private int hp;			//英雄的血量
	private int ap;			//英雄的攻击力
	
	public static class EnemyCrystal{
		private int hp = 10000;

		public int getHp() {
			return hp;
		}

		public void setHp(int hp) {
			this.hp = hp;
		}
		
		public void youWin() {
			System.out.println("英雄停止攻击");
		}
	}
	
	public Hero() {
		super();
	}
	public Hero(String name, int hp, int ap) {
		super();
		this.name = name;
		this.hp = hp;
		this.ap = ap;
	}
	
}
如何创建静态内部类对象

外部类类名.内部类类名 对象名 = new 外部类类名.内部类类名(实参);

public class Test {

	public static void main(String[] args) {
		Hero.EnemyCrystal ec = new Hero.EnemyCrystal();
		
	}
}

为什么需要静态内部类?

它不像普通内部类,普通内部类是一个对象对应一个内部类对象。静态内部类是一个独立的个体。

拿敌方水晶为例,所有英雄公用一个水晶。地方水晶被摧毁之后,我方英雄都会赢。

package com.lanou.staticinnerclass;

public class Hero {
	private static boolean gameOver = false;//游戏是否结束
	private String name;	//英雄的名字
	private int hp;			//英雄的血量
	private int ap;			//英雄的攻击力
	
	public static class EnemyCrystal{
		private int hp = 10000;

		public int getHp() {
			return hp;
		}

		public void setHp(int hp) {
			this.hp = hp;
		}
		
		public void youWin() {
			System.out.println("英雄停止攻击");
			test();
		}
	}
	
	public void attack() {
		if(gameOver == true) {
			System.out.println("stop");
		}else {
			System.out.println("正常攻击");
		}
	}
	
	public static void test() {
		gameOver = true;
	}
	
	public Hero() {
		super();
	}
	public Hero(String name, int hp, int ap) {
		super();
		this.name = name;
		this.hp = hp;
		this.ap = ap;
	}
	
}
package com.lanou.staticinnerclass;

public class Test {

	public static void main(String[] args) {
		Hero.EnemyCrystal ec = new Hero.EnemyCrystal();
		
		Hero h1 = new Hero("盖伦", 500, 70);
		Hero h2 = new Hero("盲僧", 480, 80);
		h1.attack();
		h2.attack();
		ec.youWin();
		h1.attack();
		h2.attack();
	}

}

静态内部类只能访问外部类的静态方法和静态属性。

上述代码模拟的是:水晶被打烂,英雄停止攻击。

局部类(本地类) local class

局部变量指的是方法中定义的变量,局部类指的是方法中定义的类。

局部类的定义:

public class TestLocalClass {

	public static void main(String[] args) {
		class AA{
			private int a;
			public double b;
			public void test() {
				
			}
			public AA(int a, double b) {
				super();
				this.a = a;
				this.b = b;
			}
			
		}
		
		AA a = new AA(100,25.8);

	}

}

局部类不能使用public,protected,private等关键字。因为本身是局部,只能作用这个方法,作用不到这个包的其他类里,更作用不到其他包里。

局部类的声明周期很短,方法一结束,类就消失了。

局部类中可以使用方法内的变量,但是变量会被编译器定义为final类型。

匿名内部类

匿名内部类类是局部类的一种特殊形式。

匿名:就是没名字。

匿名类:没有名字的类。

问题:一个类,没有名字怎么创建对象?

正常创建一个对象的语法格式:类名 对象名 = new 类名(实参);

现在的问题是没有类名了,如何创建对象。

匿名类的用途
  1. 作为抽象类的子类。
  2. 作为接口的实现类。
匿名类作为抽象类的子类

假定有如下抽象类:

public abstract class Shape {
	private int numberOfSide;	//边数
	public abstract double area();		//面积
	public abstract double perimeter();	//周长
	public int getNumberOfSide() {
		return numberOfSide;
	}
	public void setNumberOfSide(int numberOfSide) {
		this.numberOfSide = numberOfSide;
	}
	public Shape() {
		super();
	}
	public Shape(int numberOfSide) {
		super();
		this.numberOfSide = numberOfSide;
	}
	@Override
	public String toString() {
		return "Shape [numberOfSide=" + numberOfSide + "]";
    }
}

抽象类的正常用法: 定义一个子类,子类实现抽象类中没有实现的方法

public class Rectangle extends Shape {
	
	private double width;
	private double height;
	
	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}

	
	public Rectangle() {		
		super(4);
	}

	public Rectangle(double width, double height) {
		super(4);
		this.width = width;
		this.height = height;
	}

	@Override
	public double area() {
		return width * height;
	}

	@Override
	public double perimeter() {
		return 2 * (width + height);
	}

}

使用的时候,创建子类对象,而不是抽象类对象。

使用匿名类完成抽象类尚未完成的功能:

public class Test {

	public static void main(String[] args) {
		Rectangle rect1 = new Rectangle(10, 8);
		System.out.println(rect1.perimeter());
		System.out.println(rect1.area());
		
		int radius = 20;
		
		Shape s = new Shape() {
			@Override
			public double area() {
				
				return radius * radius * Math.PI;
			}
			@Override
			public double perimeter() {
				return 2 * Math.PI * radius;
			}
		};
		System.out.println(s.area());
		System.out.println(s.perimeter());
		
		int side = 8;
		Shape s2 = new Shape() {

			@Override
			public double area() {
				return side * side;
			}

			@Override
			public double perimeter() {
				// TODO Auto-generated method stub
				return 4 * side;
			}
			
		};
		System.out.println(s2.area());
		System.out.println(s2.perimeter());
	}

}

匿名类通常作为抽象类的子类。 抽象类之所以不能创建对象,是因为抽象类中有没有实现的方法。

如果实现了这些方法就可以正常创建对象了。例如:子类继承抽象类,实现抽象类中没有实现的方法。

再例如:匿名类实现抽象方法。

因为匿名类没有名字,所以使用起来比较怪异,它不能像普通类一样创建对象,也不能像普通类一样定义类(class 类名)。所以创建匿名类的语法比较怪异。

匿名类的创建和匿名类的对象的创建是一体的。

语法格式 new 抽象类类名(实参){ 实现抽象方法,以及定义属性以及方法 }

实际上定义属性和方法没有意义?因为定义完以后也没有办法调用。

匿名类的好处:可以不用新建一个文件(类)。

匿名类作为接口的实现类

假定有如下接口:

public interface CalculateInterface<X, Y, Z> {
	public Z operator(X t1, Y t2);
}

正常情况下,要编写接口的实现类,实现类去实现接口中定义的方法。

public class Sum implements CalculateInterface<Integer, Integer, Integer> {

	@Override
	public Integer operator(Integer t1, Integer t2) {
		return t1 + t2;
	}

}
public class Test {

	public static void main(String[] args) {
		Sum s = new Sum();
		int n = s.operator(100, 200);
		System.out.println(n);
	}

}

匿名类实现接口:

public class Test {

	public static void main(String[] args) {
		
		CalculateInterface<Integer, Double, Double> c = new CalculateInterface<Integer, Double, Double>() {
			@Override
			public Double operator(Integer t1, Double t2) {
				return t1 - t2;
			}
		};
		System.out.println(c.operator(123, 321.5));
	}

}

匿名类本质上和实现类没有什么区别,都实现了接口中定义的方法。

唯一的区别就是,实现类有自己的名字,匿名类有没有类名。

匿名类实现接口的语法格式和 匿名类继承抽象类语法格式一样:

接口名 对象名 = new 接口名(){接口中的方法实现};

总结

成员内部类,静态内部类,局部内部类不用刻意去记。

匿名类必须要会,不会是不可能的,因为天天用。

匿名类往往用于接口!接口都是别人(系统)定义好的,我们所要做的事情就是通过匿名类创建对象。

匿名类作为抽象类的子类: 抽象类类名 对象名 = new 抽象类类名(实参){ 实现还抽象方法};

匿名类作为接口的实现类:接口名 对象名 = new 接口名(){实现接口中的方法};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值