成员内部类
概述:一个类的内部又包含了一个完整的类
特点:
1.外部类和内部类都可以生成独立字节码文件
2.内部类可直接使用外部类的私有成员属性,而不破坏封装性
3.外部类的具体实现可以交给内部类来完成 1 实例内部类
实例内部类用法: 1.使用特点 2.调用方式
class Outter{ //外部类
private String name="凤姐";
public int add(int a,int b) {
return new Inner().addFun(a, b); //具体功能交给内部类完成
}
class Inner{ //实例内部类: 在外部类中包含的一个类
//The field count cannot be declared static in a non-static inner type, unless initialized with a constant
private final static int count =1; //只能用静态常量,不能直接用静态变量
//private String name="刘亦菲";
public int addFun(int a,int b) {
return a+b;
}
public void innerTest() {
//如果外部类和内部类属性出现重名,内部类优先
System.out.println(name); //可以直接使用外部类的私有成员
}
}
}
public class Test1 {
public static void main(String[] args) {
//方式1:实例化外部类对象,调用add方法
Outter outter = new Outter();
System.out.println(outter.add(1, 2));
//方式2:直接实例化内部类对象,调用内部类的方法(了解)
Outter.Inner inner = new Outter().new Inner();
System.out.println(inner.addFun(3, 4));
inner.innerTest(); //
}
}
静态内部类
静态内部类:需要+static进行修饰的内部类
使用特点: 在静态内部类中,不能使用外部类的成员属性
class Outter{
private static int a = 1;
private int b = 2;
public static class Inner{
public void test() {
System.out.println(a);
//System.out.println(b); //加载时机问题
}
}
}
public class Test1 {
public static void main(String[] args) {
//调用静态内部类方式1:
Outter.Inner inner = new Outter.Inner();
inner.test();
//直接new一个静态内部类方式2:
Inner inner2 = new Inner();
}
}
局部内部类
局部内部类:在外部类的方法中定义的一个类; 外界是不能调用的
不能在局部内部类中加权限修饰--例如:public权限
局部内部类,只能在方法内部去调用它
class Outter{
private String name="凤姐";
public void show() {
final String name2 = "刘亦菲"; //在局部内部类中如果使用了外部类的局部变量,则会默认+final
class Inner{
private String name = "芙蓉";
public void test(){
System.out.println("局部内部类的方法--"+name); //芙蓉
System.out.println(Outter.this.name); //凤姐
System.out.println(name2); //刘亦菲
}
}
new Inner().test(); //在外部类方法中才能调局部内部类
}
}
public class Test1 {
public static void main(String[] args) {
new Outter().show();
}
}
匿名内部类(重点)
匿名内部类:本质就是多态,只要能用上之前的抽象类或接口实现多态,则肯定能用匿名内部类
======================直接赋值的匿名内部类=====================
案例:喷火娃具备喷火的能力
分析:
类 Person Fireable接口
方法: 重写fire fire
interface Fireable{
void fire();
}
class Person implements Fireable{
@Override
public void fire() {
System.out.println("喷火娃在喷火...");
}
}
public class Test1 {
public static void main(String[] args) {
//---接口实现多态---
Fireable fireable = new Person();
fireable.fire();
//----匿名内部类----
Fireable fireable2 = new Fireable() {
@Override
public void fire() {
System.out.println("匿名内部类在喷火...");
}
};
fireable2.fire();
}
}
======================传参形式的匿名内部类=====================
匿名内部类与接口实现多态的应用场景:
当项目中需要多次实例化对象---接口实现多态
当进行简单测试或实例化一次对象时---匿名内部类
匿名内部类以传参形式出现:
案例:电脑连接usb的鼠标
interface USB{
void run();
}
class Mouse implements USB{
@Override
public void run() {
System.out.println("鼠标正在运转..");
}
}
class Computer{
public void connect(USB usb) {
usb.run(); //接口回调
}
}
public class Test2 {
public static void main(String[] args) {
//接口以传参形式实现多态
new Computer().connect(new Mouse());
//匿名内部类:以传参形式出现
new Computer().connect(new USB() {
@Override
public void run() {
System.out.println("匿名内部类,以传参方式出现---run重写");
}
});
}
}
======================匿名内部类扩展案例=====================
匿名内部类的扩展应用:
案例: 使用工具类,测试一段代码执行的时间,要求使用匿名内部内方式进行接口回调
提示:
测试时间的方法:System.currentTimeMillis()
分析:
接口: ITest 标准:codeTest
工具类: Tool 静态方法: getTime;
好处:使用匿名内部类后,使得程序的扩展性,维护性,复用性更强
说明:在后续的过滤器,拦截器,spring内部源码都有匿名内部类的思想
interface ITest{
void codeTest();
}
class Tool{
public static long getTime(ITest test) {
long start = System.currentTimeMillis();
test.codeTest(); //接口回调
long end = System.currentTimeMillis();
return end-start;
}
}
public class Test3 {
public static void main(String[] args) {
/*
long start = System.currentTimeMillis();
//执行的代码
long end = System.currentTimeMillis();
System.out.println(end-start);
*/
long timer = Tool.getTime(new ITest() {
@Override
public void codeTest() {
//放测试代码的区域
String s = "";
for(int i=0;i<10000;i++) {
s+=i;
}
}
});
System.out.println(timer);
}
}
浙公网安备 33010602011771号