内部类
- 定义在一个类内部,或方法内部,或局部代码快内部的类
内部类的使用情况:
外部类和内部类关系紧密,看个人设计选择
隐藏类型
作为外部类私有成员的一个访问窗口
临时使用一次的类
内部类与外部类没有访问限制
公共类public类只能有一个
非静态内部类
- 非静态属于对象、实例
class A{
//非静态内部类,前面没有static
class Lnner{
}
}
- 非静态内部类对象创建方式:
A a=new A();
A.Linner inner =a.new Linner();
- 非静态属于类,所以非静态内部类依赖于外部类对象存在
- 非静态内部类中不能定义静态成员
静态内部类
- 静态属于类,不依赖于对象
class A{
//静态内部类,前面有static
static class Lnner{
}
}
- 静态内部类对象的创建方式
A.Linner inner=new A.Linner();
局部内部类
- 在方法里或局部代码块里定义的类
//类里面有一个方法
Class A{
//方法里面定义一个类
void a(){
class Linner{
}
}
}
- 局部定义的类型,只能在局部代码块中使用,外面无法使用。(在哪定义在哪用)
Class A{
void a(){
class Linner{
// 在哪定义在哪用
Linner inner=new Linner();
}
}
}
- 对象创建出来之后,会有一个内存地址,这个内存地址保存在(inner)变量里面。
Inner inner=new Inner();
- 但是我们可以把inner内存地址的值从方法返回到外面,外面得到这个内存地址,也就可以访问这个对象
注:Inner 对象不能用自己的真实类型返回,可以用它的父类型返回,让inner对象继承Weapon接口,这样可以用它的父类型返回。Inner对象会向上转型,转成父类型返回回去
Class A{
Weapon a(){
//局部内部类
class Inner implenments Weapon{
}
//在哪定义在哪用
Inner inner=new Inner();局部内部类对象
return inner; //对象的内存地址,可以从方法返回到外面
}
}
- 使用:
A a=new A();
//定义一个变量,用于保存这个方法返回的对象内存地址
Weapon w= a.a();
匿名内部类
父类 a=new 父类(){
//new匿名子类,匿名子类继承父类
}
案例:
内部类与匿名内部类
- 案例1:新建测试类Test1:
public class Test1 {
public static void main(String[] args) {
A.Inner2 i2 = new A.Inner2();
System.out.println("创建了静态内部类对象");
A a = new A();
A.Inner1 i1 = a.new Inner1();
System.out.println("创建了非静态内部类对象");
}
}
//为方便测试参照所以在Test1类中创建了两个类,以后不建议这么写
class A {
class Inner1 {
}
static class Inner2 {
}
}
- 案例2:局部内部类:新建Weapon接口
public interface Weapon {
/*public abstract*/
void kill();
}
- 案例2:局部内部类、匿名内部类:新建测试类Test2
public class Test2 {
public static void main(String[] args) {
//接口实现类调用a()方法,得到武器对象,将方法的返回值赋给w1
//a()方法内部要创建一个Weapon子类(武器)对象,并传递出来
Weapon w1 = a();
w1.kill();
System.out.println("----------------------");
// 接口实现类调用b()方法,得到新的武器对象,让b()方法创建一个指定名称的武器。
// 创建一个指定名称的武器
Weapon w2 = b("倚天剑");
w2.kill();
}
//a()方法
private static Weapon a() {
//子类作为局部内部类来定义
class AK47 implements Weapon {
//实现接口,实现接口的抽象方法
public void kill() {
System.out.println(
"AK47开火");
}
}
//我们只能在a()方法中使用AK47类,但是我们能创建对象,转型成父类型,传递出去
AK47 a = new AK47();
//转型成父类型传递到外面
return a;
}
}
//b()方法
static Weapon b(final String name) {
//与方法a()相同,不同点是定义了一个没有名字的类
//这个类名只能在b()方法中使用,可以省略,使用没有名字的类
//class YiGeKeYiZhiDingMingChengDeWuqi
// 匿名子类实现 Weapon 接口
Weapon w = new Weapon() {
//实现接口,实现接口的抽象方法
public void kill() {
/* 局部内部类中,
* 使用外面的局部变量,
* 必须加 final */
System.out.println(
"使用"+name+"进攻");
}
};
return w;
}