Java内部类创建、通信、匿名函数

1 非静态内部类、静态内部的初始化

public class OuterClass {
    //静态内部类
    static class StaticInnerClass {
        //静态内部类中,可以定义静态及非静态方法/变量
        public static String staticFlag;
        public String nonStaticFlag;
        public static void printStaticFlag(String flag) {
            StaticInnerClass.staticFlag = flag;
            System.out.println("Call static method in staticInnerClass : " + flag);
        }
        public void printNonStaticFlag(String flag) {
            this.nonStaticFlag = flag;
            System.out.print("Call non-static method in staticInnerClass : " + flag);
        }
    }

    //非静态内部类
    class NonStaticInnerClass {
        public String flag;
        public void printFlag(String flag) {
            this.flag = flag;
            System.out.println("Call non-static method in NonStaticInnerClass : " + flag);
        }
    }

    //在外部类的静态方法中,初始化内部类
    //外部类中,内部类是可见的
    public static void staticFunction() {
        //1 不用实例化静态内部类,可以直接调用静态内部类的静态方法
        StaticInnerClass.printStaticFlag("Static method in StaticInnerClass");
        //2 外部类的静态方法中,可以调用静态内部类,不能直接创建非静态内部类
        StaticInnerClass staticInnerClass = new StaticInnerClass(); //Right
        //NonStaticInnerClass nonStaticInnerClass = new NonStaticInnerClass(); //Wrong
        //3 外部类的静态方法中,可以先实例化外部类,再创建非静态内部类
        OuterClass outerClass = new OuterClass();
        NonStaticInnerClass nonStaticInnerClass = outerClass.new NonStaticInnerClass();
    }

    //在外部类的非静态方法中,初始化内部类
    public void nonStaticFunction() {
        // 非静态方法中,可以使用静态内部类、非静态内部类
        // 外部类中,内部类是可见的
        StaticInnerClass staticInnerClass = new StaticInnerClass();
        NonStaticInnerClass nonStaticInnerClass = new NonStaticInnerClass();
        nonStaticInnerClass.printFlag("Non-static method in NonStaticInnerFunction");
    }

    //外部类中,直接创建静态内部类、非静态内部类
    StaticInnerClass staticInnerClass = new StaticInnerClass();
    NonStaticInnerClass nonStaticInnerClass = new NonStaticInnerClass();
}

上述代码中,针对静态内部类、非静态内部类共有三种创建方法

第一:静态方法中,可以直接创建静态内部类,无法直接创建非静态内部类。先实例化外部类,再通过OutClass.new 可创建非静态内部类;我的理解是:非静态依附于类的实例化,无法独立于类而存在。

第二:非静态方法中,可以直接创建静态内部类、非静态内部类;

第三:在外部类中,可以直接创建静态内部类、非静态内部类。

参考链接:静态内部类与非静态内部类的区别

                 Java静态内部类、非静态内部类的加载顺序

2 内部类访问外部类成员

public class OuterClassOne {
    public String publicName;
    private String privateName;

    class InnerClass{
        public void setName(String publicStr, String privateStr) {
            publicName = publicStr;
            privateName = privateStr;
        }
        public void printName() {
            System.out.println("public variable in OuterClassOne : " + publicName);
            System.out.println("private variable in OuterClassOne :" + privateName);
        }
        public OuterClassOne getOutClass() {
            return OuterClassOne.this;//在内部类中,获取对外部类的引用
        }
    }

    public static void main(String[] args) {
        OuterClassOne outerClassOne = new OuterClassOne();
        OuterClassOne.InnerClass innerClass = outerClassOne.new InnerClass();
        innerClass.setName("public-variable","private-variable");
        innerClass.printName();
        System.out.println("OuterClassOne reference : " + innerClass.getOutClass().toString());
    }
}
/* Output:
public variable in OuterClassOne : public-variable
private variable in OuterClassOne :private-variable
OuterClassOne reference : one.OuterClassOne@1b6d3586
 */

如代码所示,内部类具备所有外部类成员的访问权限,即使是private权限。原因:当外部类创建内部类对象时,内部类会获取指向该外部类对象的引用,并通过该引用来访问外部类的成员。如果想在内部类中获取对外部类的引用,可以使用OuterClassOne.this。

3 匿名函数

匿名函数就是不具名函数,主要特征就是用后即丢,一次性使用。主要用于接口实现,对比下即可发现:

3.1 普通情况(不使用匿名函数)

//不使用匿名类
//定义一个接口
interface Person {
    public String getName();
    public int getID(int id);
}

public class SchoolPerson {
    //实现Person类
    class Student implements  Person {
        String name = "DuJing";
        public String getName() { return name; }
        public int getID(int id) { return id; }
    }

    public  Person getPerson() { return new Student();}//调用Student类的默认构造函数
    public static void main(String[] args) {
        SchoolPerson schoolPerson = new SchoolPerson();//调用SchoolPerson类的默认构造函数
        Person student = schoolPerson.getPerson();
        System.out.println("Student name : " + student.getName());
        System.out.println("Student ID : " + student.getID(888));
    }
}
/* Output:
Student name : DuJing
Student ID : 888
 */

现在我们假设该Student的定义只会使用一次,那么这个类也没必要出现,使用匿名函数代码如下:

3.2 使用匿名类

//使用匿名类
//定义一个接口
interface Person {
    public String getName();
    public int getID(int id);
}

public class SchoolPerson {
    public  Person getPerson() {
        return new Person(){
        String name = "DuJing";
        public String getName() { return name; }
        public int getID(int id) { return id; }
    };
    }
    public static void main(String[] args) {
        SchoolPerson schoolPerson = new SchoolPerson();//调用SchoolPerson类的默认构造函数
        Person student = schoolPerson.getPerson();
        System.out.println("Student name : " + student.getName());
        System.out.println("Student ID : " + student.getID(888));
    }
}
/* Output:
Student name : DuJing
Student ID : 888
 */

对比3.1不使用匿名类、3.2使用匿名类的代码发现:使用匿名类后,即将原先Student类的定义转移至getPerson()方法中,其余代码没有变动。Student类变成了匿名类,该类的定义只有在调用getPerson()方法时才会出现。

3.3 普通类的匿名类(普通类、带有构造函数、能够传参)

//基类,含有构造函数、内部方法、变量等
class Person {
    public String name;
    public int ID;
    Person(String str, int id) { this.name = str; this.ID = id;}
    public void getPersonMessage() {System.out.println("Person name : " + name  + " Person ID : " + ID);}
    public int getID() { return ID; }
}

public class SchoolPerson {
    public  Person getPerson() {
        //匿名类,相当于继承Person,产生新的无具名类
        return new Person("DuJing",888){//调用基类的构造函数
            public int getID() { return super.getID() + 1000;}//覆盖基类的getID()方法
        };
    }
    public static void main(String[] args) {
        SchoolPerson schoolPerson = new SchoolPerson();//调用SchoolPerson类的默认构造函数
        Person student = schoolPerson.getPerson();//使用基类Person指向不具名的子类
        System.out.print("student message : ");
        student.getPersonMessage();//调用匿名类方法,与基类中的定义相同
        System.out.println("student new ID : " + student.getID());//调用匿名类方法,与基类中的定义不同
    }
}
/* Output:
student message : Person name : DuJing Person ID : 888
student new ID : 1888
 */

通过代码得出:

第一:不仅是接口类,普通类,哪怕是包含构造函数,也可以进行匿名类设计;

第二:针对接口类,其匿名类相当于implements。针对普通类,其匿名类相当于extends,且可以覆盖原有的函数定义

第三:匿名类的定义只会在调用对应代码块的时候才会加载。

第四:匿名类可以传参,且能够调用基类的构造函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值