内部类与匿名内部类

Posted Zennon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部类与匿名内部类相关的知识,希望对你有一定的参考价值。


内部类:

* 什么是内部类: 就是在一个类的里面,在定义一个类
* 一般用来描述事物之间的所属关系, 比如: 汽车事物里面需要描述发动机,可以使用内部类.
* 比如: 怀宝宝的动物
*
* 成员变量: 定义在类的里面,方法的外面
* 局部变量: 定义在方法的里面
*
* 内部类的分类:
* 成员内部类: 定义在内的里面,方法的外面
* 局部内部类(匿名内部类): 方法的里面
*
* 成员内部类的定义:
* public class 外部类{
* // 成员变量
*
* // 内部类
* public class 内部类{
* // 内部类的成员变量和成员方法
* }
* }
*
* 举个例子:
* 描述一个身体里面有一个心脏类;
*

* 内部类的特点:
* 1. 在内部类中(里面)可以访问,外部类的任意内容
* 2. 如何创建一个内部类对象呢? 
* 格式: 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
* 3. 在外部类中,不能访问内部类的任何内容.

public class Demo01InnerClass {

public static void main(String[] args) {
//Heart h = new Heart();

//创建一个内部类对象: 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
Body.Heart bh = new Body().new Heart();
bh.show();
//System.out.println(bh.life);


}
}

package package10InnerClass;

public class Body {

// 成员变量
private boolean life = true;

// 成员内部内部类
public class Heart{
// 内部类的成员变量
int blood = 60;

// 内部类的成员方法
public void show(){
System.out.println("生命状态:"+life + ", 血量:"+blood);
}
}

public void method(){
//System.out.println(blood);
// 如果想要访问内部类的内容,需要创建对象
System.out.println(new Body().new Heart().blood);
System.out.println(/*new Body().*/new Heart().blood);
}
}

  

* 如何在内部类中,出现了和外部类同名的成员变量该如何去访问?
* 格式: 外部类名.this.成员变量

public class Demo01InnerClassNotice {

public static void main(String[] args) {

new Outer().new Inner().method();

}
}

package package11InnerClass;

public class Outer {

private int num = 10;

/*
* Inner类和Outer类并不是继承关系
*/
public class Inner{
private int num = 20;

public void method(){
int num = 30;

System.out.println("局部变量 = " + num);// 30
System.out.println("本类变量 = " + this.num);//20 使用this区分
/*
* 在内部类中访问外部类的格式: 外部类名.this.成员变量
*/
System.out.println("外部变量 =" + Outer.this.num);// 10
}
}
}

  

 

匿名内部类:


* 内部类分成两种:
* 成员内部类:
* 局部内部类: 定义在方法里面
*
* 匿名内部类的格式:
* 接口/抽象类 变量名 = new 接口/抽象类(){
* // 重写抽象方法
* };
*
* 格式解释:
* 1. 等号的右边大括号{}, 表示定义了一个匿名的内部类.
* 2. 等号右边的new 接口(), 表示创建了匿名内部类的一个对象
* 3. 等号左边,使用接口去接收了,匿名内部类的对象;// 多态
*
* 作用:
* 没有学习匿名内部类之前,如果要想使用接口或者抽象类,必须创建实现类,或者子类,才能使用
* 有了匿名内部类之后,可以简化了.

public class Demo01NoNameInnerClass {

public static void main(String[] args) {

//method(new Cat());

// 创建匿名内部类对象, 使用对象名接收
Animal ani = new Animal(){

// 重写抽象方法
public void eat(){
System.out.println("小狗吃骨头");
}
};

method(ani);

// 创建匿名内部类的匿名对象,调用方法
new Animal(){
public void eat(){
System.out.println("小猪吃白菜");
}
}.eat();

System.out.println("==================");
}

public static void method(Animal ani){
ani.eat();
}
}

package package12NoNameInnerClass;
//动物接口
public interface Animal {

public abstract void eat();
}

package package12NoNameInnerClass;
//猫类实现动物接口
public class Cat implements Animal{

public void eat(){
System.out.println("猫吃鱼");
}
}

  


例题:

package cn.itcast.fudao03;
/*
* 某市举办一场运动会,只要是会跑的都可以参加.
要求: 使用到接口,接口作为参数,匿名内部类.
提示: 把跑功能抽取到接口中 ,在测试类中提供参加运动会的静态方法 
*/
public class Test01 {

public static void main(String[] args) {
new Sport() {

@Override
public void run() {
System.out.println("参加运动会,奔跑吧小鸡儿飞");
}
}.run();;
}

public static void enterSport(Sport s){
s.run();
}

}


package cn.itcast.fudao03;

public interface Sport {
public abstract void run();
}

  


* 类作为方法的参数和返回值:
* 不管是JDK提供的类,还是自定义的类,都可以作为方法的参数和返回值
* 抽象可不可以作为方法的参数和返回值呢? 可以
* 接口能不能作为方法的参数和返回值? 可以

如:

package package13ClassAsParaReturn;
//抽象动物类
public abstract class Animal {

public abstract void eat();
}

package package13ClassAsParaReturn;
//人类
public class Person {

String name;
int age;

public void eat(){
System.out.println("吃饭了....");
}
}

package package13ClassAsParaReturn;
//吸烟接口
public interface SmokerInter {

public abstract void smoke();

public abstract void tangtou();
}


package package13ClassAsParaReturn;
/*
* 类作为方法的参数和返回值:
* 不管是JDK提供的类,还是自定义的类,都可以作为方法的参数和返回值
*/
public class Demo01ClassASParaReturn {

public static void main(String[] args) {


// Object obj = null;
// ((String)obj).length();

// String作为方法的参数
String str = new String("hello");
methodString(str);

// String作为方法的返回值
System.out.println(methodString2());
char[] array = methodString2().toCharArray();// 链式编程, 条件: 需要方法有返回值

// person类作为方法的参数
methodPerson(new Person());

// Person类作为方法的返回值
if(methodPerson() instanceof Person){
Person p = (Person)methodPerson();
p.eat();
}
}

  

/*
* JDK提供的类,作为方法的参数和返回值
*/

public static void methodString(Object obj){// 多态的格式

if(obj instanceof String){
String str = (String)obj;
System.out.println(str.length());
}
}

public static String methodString2(){
return new String("helloworld");
}

/*
* 自定义的Person类作为方法的参数和返回值
*/
public static void methodPerson(Person p ){
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p);// 地址值: 包名 + @ + 地址值
}

public static Object methodPerson(){
return new Person();
}
}

 

/*
* 抽象可不可以作为方法的参数和返回值呢? 可以
*/ 
package package13ClassAsParaReturn;
/*
* 抽象可不可以作为方法的参数和返回值呢? 可以
*/
public class Demo02AbstractClass {

public static void main(String[] args) {

// 调用方法,传递有名字的对象
Animal ani = new Animal(){
// 重写抽象方法
public void eat(){
System.out.println("1: 小猫吃鱼");
}
};

method1(ani);

// 调用方法,传递匿名内部类的匿名对象
method1(new Animal(){
//重写抽象方法
public void eat(){
System.out.println("2: 小狗吃骨头");
}
});

System.out.println("=============");

// 抽象类作为方法返回值
Animal ani2 = method3();
ani2.eat();

method3().eat();
}

/*

* 抽象类作为方法的参数

*/
/*
* 抽象类作为方法的参数
*/
public static void method1(Animal ani){
ani.eat();
}

  

/*
* 抽象类作为方法的返回值
*/


/*
* 抽象类作为方法的返回值
*/
public static Animal method3(){
/*
Animal ani = new Animal(){
// 方法重写
public void eat(){
System.out.println("3.小猪吃白菜");
}
};

return ani;
*/

// 返回匿名内部类的匿名对象
return new Animal(){
// 方法重写
public void eat(){
System.out.println("3.小猪吃白菜");
}
};
}
}

  

/*
* 接口能不能作为方法的参数和返回值? 可以
*/
package package13ClassAsParaReturn;
/*
* 接口能不能作为方法的参数和返回值? 可以
*/
public class Demo03InterfaceAsParaReturn {

public static void main(String[] args) {

// 1. 接口作为方法的参数传递
SmokerInter si = new SmokerInter(){
// 重写抽象方法
public void smoke(){
System.out.println("抽游泳烟");
}

public void tangtou(){
System.out.println("烫头称为红色");
}
};

method1(si);

method1(new SmokerInter(){
// 重写抽象方法
public void smoke(){
System.out.println("2抽游泳烟");
}

public void tangtou(){
System.out.println("2烫头称为红色");
}
});


System.out.println("=============");

// 接口作为方法的返回值传递
SmokerInter si2 = method2();
si2.smoke();
si2.tangtou();
}
/*
* 接口作为方法的参数传递
*/
/*
* 接口作为方法的参数传递
*/
public static void method1(SmokerInter si){
si.smoke();
si.tangtou();
}
/*
* 接口作为方法的返回值
*/
/*
* 接口作为方法的返回值
*/
public static SmokerInter method2(){
return new SmokerInter(){
public void smoke(){
System.out.println("smoke === smoke");
}

public void tangtou(){
System.out.println("tangtou === tangtou");
}
};
}
}

  


以上是关于内部类与匿名内部类的主要内容,如果未能解决你的问题,请参考以下文章

Java中的内部类与匿名内部类详解

java内部类与匿名内部类作用分别是啥?

内部类与匿名内部类

days13--内部类与匿名内部类

“全栈2019”Java第一百零六章:匿名内部类与抽象类接口注意事项

“全栈2019”Java第一百零七章:匿名内部类与构造方法注意事项