java中四种局部_java中的四种内部类

java中的内部类分为四个:

成员内部类

静态内部类

局部内部类

匿名内部类

1. 成员内部类:

定义在另一个类(外部类)的内部,而且与成员方法和属性平级叫成员内部类,......相当于外部类的非静态方法,如果被static修饰,就变成静态内部类了。

)成员内部类中不能存在static关键字,即,不能声明静态属性、静态方法、静态代码块等。【非静态内部类也可以定义静态成员但需要同时有final关键词修饰,静态方法鉴于无法用final修饰,仍必须是在静态内部类 或者非内部类中定义。】

)创建成员内部类的实例使用:外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数),可以理解为隐式地保存了一个引用,指向创建它的外部类对象。

)在成员内部类中访问外部类的成员方法和属性时使用:外部类名.this.成员方法/属性。

)内部类在编译之后生成一个单独的class文件,里面包含该类的定义,所以内部类中定义的方法和变量可以跟父类的方法和变量相同。例如上面定义的三个类的class文件分别是:MyTest.class、Outer.class和Outer$Inner.class三个文件。

)外部类无法直接访问成员内部类的方法和属性,需要通过内部类的一个实例来访问。

)与外部类平级的类继承内部类时,其构造方法中需要传入父类的实例对象。且在构造方法的第一句调用“外部类实例名.super(内部类参数)”。

//成员内部类......相当于非静态方法

class Outer{

private int a = 3;

private Inner in;

public Outer(){

in = new Inner();

}

public int getInnerA(){

return in.a; // 引用内部类的变量,需通过实例

}

public class Inner {

public int a = 2;

public void doSomething() {

// 调用外部类的属性

System.out.println(MemberInner.this.a);// 这块要注意......很重要!!!

System.out.println(a);

}

}

}

public class Test3 {

public static void main(String[] args) {

Outer.Inner inner = new Outer().new Inner();// 非静态内部类要new实例

inner.doSomething();

}

}

class Extender extends Outer.Inner{

public Extender(Outer outer){

//外部类实例名.super(内部类参数列表)

outer.super();

}

}

2.静态内部类

使用static修饰的成员内部类叫静态内部类。

可以这样理解:与外部类同级的类,或者叫做外部类的静态成员。与成员内部类的对比如下:

说明

成员内部类

静态内部类

静态成员

静态成员需同时有final关键词修饰

可以

静态方法

不可定义

可以

访问外部类非static属性/方法

外部类名.this.成员方法/属性

不可以

外部类访问内部类

需要通过内部类的一个实例来访问

需要通过内部类的一个实例来访问

创建实例

外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数)

外部类名.内部类名 实例名 = new 外部类名.内部类名(参数)

编译后的class文件

单独的class文件(so内部类中的方法和变量可以跟父类的方法和变量同名),外部类$内部类.class

单独的class文件(so内部类中的方法和变量可以跟父类的方法和变量同名),外部类$内部类.class

其他

与外部类平级的类继承内部类时,其构造方法中需要传入父类的实例对象。且在构造方法的第一句调用“外部类实例名.super(内部类参数)”

/**

* 成员内部类和静态内部类总结:

* 1.静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。

* 2.静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。

* 3.实例化一个非静态的内部类的方法:

*  a.先生成一个外部类对象实例

*  OutClassTest oc1 = new OutClassTest();

*  b.通过外部类的对象实例生成内部类对象

*  OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();

*  4.实例化一个静态内部类的方法:

*  a.不依赖于外部类的实例,直接实例化内部类对象

*  OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();

*  b.调用内部静态类的方法或静态变量,通过类名直接调用

*  OutClassTest.InnerStaticClass.static_value

*  OutClassTest.InnerStaticClass.getMessage()

*/

3.局部内部类

定义在代码块、方法体内、作用域(使用花括号“{}”括起来的一段代码)内的类叫局部内部类。

)局部内部类只能在代码代码块、方法体内和作用域中使用(如创建对象和使用类对象等)

)局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰。

)可以使用abstract修饰,声明为抽象类。

4.匿名内部类

为什么要有匿名内部类: 主要是针对那些不能直接创建对象的抽象类和接口而来的

匿名内部类定义和实例化形式如下:

new 父类构造方法(参数){

//注:该方法名必须在父类中已经存在

修饰符 返回参数类型 方法名(参数列表){

。。。

}

}

)只能使用一次,创建实例之后,类定义会立即消失(想要多次使用就要用到反射的知识了)

)必须继承一个类(抽象的、非抽象的都可以)或者实现一个接口。如果父类(或者父接口)是抽象类,则匿名内部类必须实现其所有抽象方法。

)不能是抽象类,因为匿名内部类在定义之后,会立即创建一个实例。

)不能定义构造方法,匿名内部类没有类名,无法定义构造方法,但是,匿名内部类拥有与父类相同的所有构造方法。

)可以定义代码块,用于实例的初始化,但是不能定义静态代码块。

)可以定义新的方法和属性(不能使用static修饰),但是无法显式的通过“实例名.方法名(参数)”的形式调用,因为使用new创建的是“上转型对象”(即父类声明指向子类对象)。

)是局部内部类,所以要符合局部内部类的要求。

说明

成员内部类

匿名内部类

静态成员

静态成员需同时有final关键词修饰

不可定义

静态方法

不可定义

不可定义

访问外部类非static属性/方法

外部类名.this.成员方法/属性

外部类名.this.成员方法/属性

外部类访问内部类

需要通过内部类的一个实例来访问

需要通过内部类的一个实例来访问

创建实例

外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数)

如上:父类 实例名 = new 父类(){}

编译后的class文件

单独的class文件(so内部类中的方法和变量可以跟父类的方法和变量同名),外部类$内部类.class

单独的class文件,使用类$数字.class

其他

与外部类平级的类继承内部类时,其构造方法中需要传入父类的实例对象。且在构造方法的第一句调用“外部类实例名.super(内部类参数)”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值