成员内部类
/*
* 内部类:
* 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个类的内部完整的结构又只为外部事物提供服务
* 那么整个内部的完整结构最好使用 内部类
* 在Java中,允许一个类的定义位于另一个的内部,前者为内部类,后者为外部类
* innerclass一般用在定义它的类或语句块之内,在外部引用它的时候必须给出完整的名称
* 重要作用:可以访问外部类的私有化数据
* 变量:
* 成员变量:成员内部类
* 静态变量:静态内部类
* 局部变量:局部内部类
* 形参和实参:匿名内部类
*
* 成员内部类:
* 1 可以等同看做是成员变量
* 2 成员内部类不能有静态声明
* 3 成员内部类可以直接访问外部类所有属性
* */
public class _01_OuterClass {
private static String s1 = "A";
private String s2 = "B";
// private、protected、public都可以使用
// 编译后的类名为:外部类类名$内部类类名
// _01_OuterClass$InnerClass
class InnerClass{
// 不能有静态声明
// static int x = 2;
// public static void m1(){}
public void m2(){
// 可以直接访问外部类所有属性
System.out.println(s1);
System.out.println(s2);
}
}
public static void main(String[] args) {
// 创建外部类对象
_01_OuterClass oc = new _01_OuterClass();
// 通过外部类对象去创建成员内部类对象
InnerClass ic = oc.new InnerClass();
ic.m2();
}
}
静态内部类
/*
* 静态内部类:
* 1 可以等同看做是静态变量
* 2 静态内部类可以任意声明
* 3 静态内部类不能直接访问成员数据,需要有对象才行
* */
public class _02_OuterClass {
private static String s1 = "A";
private String s2 = "B";
static int x = 2;
static class InnerClass{
public static void m1(){
System.out.println(s1);
// 不能直接访问成员属性
// System.out.println(s2);
// 需要用对象调用
_02_OuterClass oc = new _02_OuterClass();
System.out.println(oc.s2);
}
public void m2(){
System.out.println(s1);
// 不能直接访问成员属性
// System.out.println(s2);
}
}
public static void main(String[] args) {
// 外部类.静态内部类.静态方法/属性
_02_OuterClass.InnerClass.m1();
System.out.println("=========");
// 访问当前类的静态属性的时候,类名可以直接省略(外部类)
InnerClass.m1();
System.out.println("===++++");
// 创建内部类对象
InnerClass ic = new _02_OuterClass.InnerClass();
InnerClass ic1 = new InnerClass();
ic.m2();
}
}
局部内部类
/*
* 局部内部类:
* 1 等同于局部变量
* 2 在访问外部类中局部变量时候需加final修饰(1.8之前),1.8开始final可以省略
* 3 局部内部类不能有静态声明
* 4 如果是成员方法中的局部内部类,可以访问外部类中的所有属性
* 5 如果是静态方法中的局部内部类,不可以直接访问外部类的成员属性,需要创建对象去访问
* */
public class _03_OuterClass {
private static String s1 = "A";
private String s2 = "B";
public static void main(String[] args) {
_03_OuterClass oc = new _03_OuterClass();
oc.m1();
System.out.println("========");
m2();
}
// 静态方法
public static void m2(){
int i = 2;
class InnerClass{
// 不能静态声明
// public static void m1(){}
public void m4(){
System.out.println(s1);
// 是静态方法中的局部内部类,不可以访问外部类中的成员属性,需创建对象
// System.out.println(s2);
System.out.println(new _03_OuterClass().s2);
// 1.8开始,访问局部变量时候,可以不加final修饰,但 值依旧不能更改
System.out.println(i);
}
}
// 调用内部类
InnerClass ic = new InnerClass();
ic.m4();
}
// 成员方法
public void m1(){
int i = 1; // 1.8之前局部内部类在访问外部类中局部变量时候需加final修饰
// 不能使用权限修饰符
class InnerClass{
// public static void m1(){}
public void m3(){
System.out.println(s1);
// 是成员方法中的局部内部类,可以访问外部类中的所有属性
System.out.println(s2);
// 1.8开始,访问局部变量时候,可以不加final修饰,但 值依旧不能更改
System.out.println(i);
}
}
// 只能在方法中调用
InnerClass ic = new InnerClass();
ic.m3();
}
}
匿名内部类
/*
* 匿名内部类:指在方法调用时,实参需要传入某个接口对象时,不传入对象,传入一个匿名的实现类
* 如果方法定义形参 一般是一个接口,调用的时候需要传入一个其实现类的对象
* 这时可以不实现这个接口,不传递实现类对象,可以传递一个匿名内部类,这个类没有名字,不能复用
* 默认匿名内部类类名:外部类类名$ 以此类推
* 没有名字的类,无法创建对象,但传入匿名内部类时,自动创建了一个对象
*
* */
public class _04_OuterClass {
public static void main(String[] args) {
// m1()执行时发生多态。需要传入接口,但可以传入接口的实现CustomerServiceImp()
// CustomerServiceImp()继承自接口,相当于派生类
// 此时执行的是派生类的logout()方法
m1(new CustomerServiceImp());
System.out.println("===========");
// 匿名内部类写法
// 少定义一个实现类
// 但不能重复使用,当前使用
m1(new ICustomerService() {
@Override
public void logout() {
// this 表示匿名内部类的内存地址
System.out.println("退出登录"+this);
}
});
}
public static void m1(ICustomerService cs){
cs.logout();
}
}
interface ICustomerService{
void logout();
}
class CustomerServiceImp implements ICustomerService{
@Override
public void logout() {
System.out.println("退出登录");
}
}