王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

一、内部类

1.1、内部类概念

定义在一个类内部中的另一个类,被称为内部类

特点:

可以直接访问,内部类的外部类中的,成员属性和方法(包含-PRivate)

外部类要访问内部类中的成员和方法,需要先建立内部类对象

1.2、示例

packagecom.day08.innerclass.demo1;

/**

* 包含内部类

* @author denny

*

*/

public class Outer { //外部类

//private成员

private String name="张三";

private int age=20;

private String gender="男";

/**

* 内部类

*/

classInner{

private int num=3;

public voidhello(){

System.out.println("姓名:"+name+"年龄:"+age

+"性别:"+gender);

}

public intgetNum() {

returnnum;

}

public void setNum(intnum) {

this.num =num;

}

}

/*

* 外部类中的方法

*/

public voidshow(){

System.out.println("姓名:"+this.name+"年龄:"+this.age

+"性别:"+this.gender);

}

/*

* 调用内部类

*/

public voidsay(){

Inner inner=newInner();

System.out.println("调用内部类:"+"num="+inner.getNum()+", num="+inner.num);

}

publicString getName() {

returnname;

}

public voidsetName(String name) {

this.name =name;

}

public intgetAge() {

returnage;

}

public void setAge(intage) {

this.age =age;

}

publicString getGender() {

returngender;

}

public voidsetGender(String gender) {

this.gender =gender;

}

}

测试外部类

packagecom.day08.innerclass.demo1;

public classOuterTest {

public static voidmain(String[] args) {

//外部类调用内部类

Outer o=newOuter();

o.show();

o.say();

}

}

结果:

姓名:张三年龄:20性别:男

调用内部类:num=3, num=3

测试内部类

packagecom.day08.innerclass.demo1;

public classInnerTest1 {

public static voidmain(String[] args) {

// 声明内部类中对 象,先声明外部类,再声明内部类

Outer.Inner inner = new Outer().newInner();

inner.hello();

}

}

姓名:张三年龄:20性别:男

调用内部类:num=3, num=3

1.3、静态内部类

如果内部类是static修饰的就只能调用父类中static成员

声明方式,可直接外部类.内部类()来声明或者调用

packagecom.day08.innerclass.demo3;

public classOuter {

//private成员

private String name="张三";

static int age=20;

private String gender="男";

/*

* 外部类中的方法

*/

public voidshow(){

System.out.println("姓名:"+this.name+"年龄:"+this.age

+"性别:"+this.gender);

}

/**

* 内部类

*/

static classInner{

private int num=3;

public voidhello(){

System.out.println("外部类年龄:"+age

+",内部类属性"+this.num);

}

}

public static voidmain(String[] args) {

//静态内部类可以直接通过外部类.内部类声明

Outer.Inner inner=newOuter.Inner();

inner.hello();

}

}

外部类年龄:20,内部类属性3

1.4、内部类成员是static的话

这个内部类必须被static修饰,static只能调用外部类和内部类中的stiatic的成员.

packagecom.day08.innerclass.demo3;

public classOuter {

//private成员

private String name="张三";

static int age=20;

private String gender="男";

/*

* 外部类中的方法

*/

public voidshow(){

System.out.println("姓名:"+this.name+"年龄:"+this.age

+"性别:"+this.gender);

}

/**

* 内部类

*/

static classInner{

private static int num=3;

public static voidhello(){

System.out.println("外部类年龄:"+age

+",内部类属性"+num);

}

}

public static voidmain(String[] args) {

//静态内部类m成员也是静态的可以直接调用Outer.Inner.hello();

}

}

结果:外部类年龄:20,内部类属性3

1.5、声明在外部类中成员方法中的内部类

声明成员方法中的,内部类,调用成员方法中的局部变量 时,成员方法中的局部变量 必须为final修饰

packagecom.day08.innerclass.demo3;

public classOuter {

// private成员

private String name = "张三";

static int age = 20;

private String gender = "男";

/*

* 外部类中的方法

*/

public void show(intx) {

final int y = 5;

//System.out.println("姓名:" + this.name + "年龄:" + this.age + "性别:" + this.gender);

classInner {

public voidhello() {

System.out.println("hello-------"+x + " ," +y);

}

}

Inner inner = newInner();

inner.hello();

}

/**

* 内部类

*/

public static voidmain(String[] args) {

//声明成员方法中的,内部类,调用成员方法中的局部变量 时,成员方法中的局部变量 必须为final修饰

new Outer().show(8);

}

}

hello-------8 ,5

1.6、为什么内部类能直接访问外部类中的成员呢?

因为内部类持有了外部类的引用,外部类名.this。 (默认省略)

packagecom.day08.innerclass.demo4;

public classOuter {

private int num=3;

classInner{

private int num=4;

public voidshow(){

int num=5;

//局部变量System.out.println(num);

//内部类的成员变量

System.out.println(this.num);

//外部类的成员变量

System.out.println(Outer.this.num);

}

}

public static voidmain(String [] args){

new Outer().newInner().show();

}

}

二、匿名内部类

2.1、匿名内部类概念

内部类可以继承或实现一个外部类或者接口。

格式:

new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}

简单理解:

就是建立一个带内容的外部类或者接口的子类匿名对象。

什么时候使用匿名内部类呢?

通常使用方法是接口类型参数,并且该接口中的方法不超过三个,可以将匿名内部类作为参数传递。

好处:

增强阅读性。

2.2、重写类中的方法

packagecom.day08.innerclass.demo5;

/**

* 抽象类

* @author denny

*

*/

public abstract classPerson {

private String name="张三";

public voidshow(){

System.out.println(this.name);

}

publicString getName() {

returnname;

}

public voidsetName(String name) {

this.name =name;

}

}

packagecom.day08.innerclass.demo5;

/**

* 外部类

*

* @author denny 实现有一个方法的抽象类的匿名内部类

*

*/

public classOuter {

private int num = 3;

public voidsay() {

new Person() {// 匿名内部类

public void show() { //重写抽象类中的方法,抽象方法,普通方法都可以

System.out.println("..............." +num);

}

}.show(); //对象创建完成,调用自己}

public static voidmain(String[] args) {

newOuter().say();

}

}

结果:

...............3

第二种写法,适后重写了多个方法

packagecom.day08.innerclass.demo5;

/**

* 外部类

*

* @author denny 实现有一个方法的抽象类的匿名内部类

*

*/

public classOuter {

private int num = 3;

public voidsay() {

Person person=new Person() {// 匿名内部类

public void show() { //重写抽象类中的方法,抽象方法,普通方法都可以

System.out.println("..............." +num);

}

};

//对象创建完成person.show();

}

public static voidmain(String[] args) {

newOuter().say();

}

}

2.3、示例使用接口的方式

packagecom.day08.innerclass.demo6;

/**

* 接口

* @author denny

*

*/

public interfaceBirdPro {

/**

* 2个抽象方法

*/

public voidshout();

public voidaccact();

}

packagecom.day08.innerclass.demo6;

public classOuter {

private String name="张三";

public voidshow(){

int y=3;

BirdPro birdPro=newBirdPro(){

//实现接口中的方法@Override

public voidshout() {

System.out.println(name+","+y);

}

@Override

public voidaccact() {

System.out.println(y+","+name);

}

};

birdPro.shout();

birdPro.accact();

}

publicString getName() {

returnname;

}

public voidsetName(String name) {

this.name =name;

}

public static voidmain(String[] args) {

newOuter().show();

}

}

结果:

张三,3

3,张三

2.4、把匿名内部类做参数传递

通常的使用场景之一:当函数参数是接口类型时,而且接口中的方法不超过三个。可以用匿名内部类作为实际参数进行传递。

packagecom.day08.innerclass.demo6;

/**

* 接口

*

* @author denny

*

*/

public interfaceBirdPro {

/**

* 2个抽象方法

*/

public voidshout();

public voidaccact();

}

packagecom.day08.innerclass.demo6;

classInnerDemo {

public static voidmain(String[] args) {

// 把接口做参数传递

show(newBirdPro() {

// 实现接口中的方法@Override

public voidshout() {

System.out.println("叫声");

}

@Override

public voidaccact() {

System.out.println("攻击");

}

});

}

public static void show(BirdPro birdPro) {// 做参数

// 调用birdPro.accact();

birdPro.shout();

}

}

2.5、 初始化顺序

packagecom.day08.innerclass.demo2;publicclassFu {intnum = 9;static{

System.out.println(" static Fu");

}

{

System.out.println("Fu");

}

Fu() {super();//Object//显示初始化//构造代码块初始化show();//构造函数调用方法,如果子类已经重写了,父类的方法,则执行子类的方法,但这时,成员还没有初初始化,所以为默认值}voidshow() {

System.out.println("fu show " + num);//被覆盖,运行子类的}

}

packagecom.day08.innerclass.demo2;publicclassZiextendsFu {intnum = 8;static{

System.out.println(" static Zi");

}

{

System.out.println("Zi");

}

Zi(){super();//显示初始化//构造代码块初始化show();

}voidshow(){

System.out.println("zi show " +num);

}

}

packagecom.day08.innerclass.demo2;publicclassTest1 {publicstaticvoidmain(String[] args) {newZi();

}

}

结果:

staticFustaticZi

Fu

zi show0Zi

zi show8

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航