内部类

内部类的概念


 

  • 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类
  • 与之对应,包含内部类的类被称为外部类
  • 内部类隐藏在外部类之内,更好的实现了信息隐藏
  • 内部类分为:
    • 成员内部类
    • 静态内部类
    • 方法内部类
    • 匿名内部类

 
 

成员内部类


 

  • 内部类中最常见的就是成员内部类,也称为普通内部类
  • 内部类在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化
  • 内部类的访问修饰符,可以任意,但是访问范围会受到影响
  • 内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的
  • 可以使用外部类.this.成员的方式,访问外部类中同名的信息
  • 外部类访问内部类信息,需要通过内部类实例,无法直接访问
  • 内部类编译后.class文件命名:外部类$内部类.class
  • 获取成员内部类对象实例的三种方式
    • 方式一:new 外部类.new 内部类
      • Person.Heart myHeart=new Person().new Heart();
      • System.out.println(myHeart.beat());
    • 方式二:外部类对象.new 内部类
      • myHeart=lili.new Heart();
      • System.out.println(myHeart.beat());
    • 方式三:外部类对象.获取方法
      • myHeart=lili.getHeart();
      • System.out.println(myHeart.beat());

 
 

静态内部类


 

  • 静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例
  • 静态内部类对象实例时,可以不依赖于外部类对象
  • 可以通过外部类.内部类.静态成员的方式,访问内部类中的静态成员
  • 当内部类属性与外部类属性同名时,默认直接调用内部类中的成员
  • 如果需要访问外部类中的静态属性,则可以通过 外部类.属性 的方式
  • 如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性的方式
  • 获取静态内部类对象实例
    • Person.Heart myHeart=new Person.Heart();
    • System.out.println(myHeart.beat());

 
 

方法内部类


 

  • 定义在外部类方法中的内部类,也称局部内部类,作用范围也在方法内
  • 和方法内部成员使用规则一样,class前面不可以添加public、private、protected、static
  • 类中不能包含静态成员
  • 类中可以包含final、abstract修饰的成员

 
 

匿名内部类


 

  • 匿名内部类也就是没有名字的内部类
  • 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写
  • 必须继承一个父类或实现一个接口
  • 注意事项:
    • 编译后的文件命名:外部类$数字.class
    • 无法使用 public、private、protected、static 修饰,匿名内部类不能出现抽象方法
    • 无法编写构造方法,但可以添加构造代码块
    • 不能出现静态成员
    • 匿名内部类可实现接口也可以继承类,但是不可兼得
    • 匿名内部类不能是抽象的,它必须要实现继承的类或实现接口的所有抽象方法
    • 例:
public abstract class Person {
	private String name;
	
	public Person(){
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public abstract void read();
}
public class PersonTest {

	public void getRead(Person person) {
		person.read();
	}

	public static void main(String[] args) {
		PersonTest test = new PersonTest();

		test.getRead(new Person() {
			{
				// 构造代码块
			}

//			public static int age=12;
			@Override
			public void read() {

				System.out.println("男生喜欢看科幻类书籍");
			}

		});
		test.getRead(new Person() {

			@Override
			public void read() {

				System.out.println("女生喜欢读言情小说");
			}

		});
	}

}

 
 

匿名内部类的几种表现形式


 

  • 继承式的匿名内部类:

在这里插入图片描述

  • 引用变量不是引用 Car 对象,而是 Car 匿名子类的对象
  • 建立匿名内部类的关键点是重写父类的一个或多个方法
  • 接口式的匿名内部类:

在这里插入图片描述

  • 接口式的匿名内部类是实现了一个接口的匿名类,而且只能实现一个接口
  • 参数式的匿名内部类

在这里插入图片描述

  • 由上面的三个例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现。最常用的情况就是在多线程的实现上,因为要实现多线程必须继承 Thread 或是实现 Runnable 接口
  • Thread 类的匿名内部类实现:

在这里插入图片描述

  • Runnable 接口的匿名内部类实现

在这里插入图片描述

 
 

接口中的内部类


 

  • 在实际开发过程中,如果想要创建某些公共代码,使得它们可以被某个接口的所有不同实现所共用,那么接口内部的嵌套类会显得很方便
  • 在接口中可以含有内部类
  1. 首先创建接口,接口中定义了普通内部类 InnerClass 和抽象内部类 AbInnerClass

在这里插入图片描述

  1. 普通成员内部类的实例化
  • 创建接口的实现类 ClassDemo

在这里插入图片描述

  • 获取普通内部类对象,调用方法

在这里插入图片描述

  • 运行结果:

在这里插入图片描述

  1. 抽象成员内部类的实例化
  • 创建接口的实现类 AbClassDemo

在这里插入图片描述

  • 获取抽象内部类对象,调用方法

在这里插入图片描述

  • 运行结果:

在这里插入图片描述

 
 

案例总结


 

//接口Ball
public interface Ball {
    //创建抽象方法play():void
    void play();
}
public class BallTest implements Ball {
    //无参构造
    public BallTest() {
         
    }
 
    @Override
    public void play() {
        // TODO 自动生成的方法存根
 
    };
 
    public void playBall(Ball ball) {
        ball.play();
    };
   //获取成员内部类对象
    public Inner_m getInner_m() {
        return new Inner_m();
    }
 
    // 创建成员内部类Inner_m
    public class Inner_m implements Ball {
 
        @Override
        public void play() {
            System.out.println("成员内部类:\n打篮球");
 
        }
 
    }
 
    // 创建方法内部类
    public void info() {
        class Inner_f implements Ball {
            @Override
            public void play() {
                System.out.println("***************\n方法内部类:\n打乒乓球");
 
            }
        }
        Inner_f balltwo = new Inner_f();
        balltwo.play();
    }
 
}
public class Test {
 
    public static void main(String[] args) {
        BallTest ball = new BallTest();
        // 方式1:外部类名.内部类名 标识符 = new 外部类().new 内部类()
        BallTest.Inner_m ballone = new BallTest().new Inner_m();
        // 方式2:外部类对象.new 内部类
        ballone = ball.new Inner_m();
        // 方式3:外部类对象.获取方法
        ball.getInner_m();
        ball.playBall(ballone);
 
        // 获取方法内部类对象
        ball.info();
 
        // 匿名内部类
        ball.playBall(new BallTest(){
            @Override
            public void play() {
                System.out.println("***************\n匿名内部类:\n打排球");
            }
        });
     
    }
 
}

 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值