inner classes in methods and scopes

本文深入探讨了Java中局部内部类的使用场景与实现原理。解释了局部内部类如何在方法或任意作用域内创建,以及为何选择这种方法:一是为了实现某种接口并返回引用;二是为了解决复杂问题而创建辅助类,但不希望其公开。文章通过具体示例展示了局部内部类的定义和使用。

Inner classes can be created within a method or even an arbitrary scope. There are two reasons for doing this:

1. We’re implementing an interface of some kind so we can create and return a reference.

2. We’re solving a complicated problem and we create a class to aid in we solution, but we don’t want it publicly available.


local inner class (an entire class within the scope of a method), for example:

// innerclasses/Parcel5.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Nesting a class within a method

public class Parcel5 {
  public Destination destination(String s) {
    final class PDestination implements Destination { // not have an access specifier
      private String label;

      private PDestination(String whereTo) {
        label = whereTo;
      }

      @Override
      public String readLabel() {
        return label;
      }
    }
    return new PDestination(s); // upcasting
  }

  public static void main(String[] args) {
    Parcel5 p = new Parcel5();
    Destination d = p.destination("Tasmania");
  }
}

The upcasting in the return statement means nothing comes out of destination() except a reference to a Destination interface. The fact that the name of the class PDestination is placed inside destination() doesn’t mean PDestination is not a valid object once destination() returns. We can use the class identifier PDestination for an inner class inside each class in the same subdirectory without a name clash.

Then, see how we can nest an inner class within any arbitrary scope:

// innerclasses/Parcel6.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Nesting a class within a scope

public class Parcel6 {
  private void internalTracking(boolean b) {
    if (b) {
      class TrackingSlip { // inner class, after compiled it is Parcel6$1TrackingSlip.class
        private String id;

        TrackingSlip(String s) {
          id = s;
        }

        String getSlip() {
          return id;
        }
      }
      TrackingSlip ts = new TrackingSlip("slip");
      String s = ts.getSlip();
    }
    // Can't use it here! Out of scope:
    // - TrackingSlip ts = new TrackingSlip("x"); // [1]
  }

  public void track() {
    internalTracking(true);
  }

  public static void main(String[] args) {
    Parcel6 p = new Parcel6();
    p.track();
  }
}

[1]'s compile error:

innerclasses/Parcel6.java:25: error: cannot find symbol
    TrackingSlip ts = new TrackingSlip("x");
    ^
  symbol:   class TrackingSlip

references:

1. On Java 8 - Bruce Eckel

2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/Parcel5.java
3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/Parcel6.java

在编程中,函数和变量的作用域是理解程序结构和行为的关键概念。变量的作用域定义了程序中可以访问该变量的区域,而函数则提供了将代码组织成可重用和模块化单元的能力。以下内容涵盖了函数的基本概念、变量作用域的规则以及与作用域相关的关键词。 ### 函数的基本概念 函数是组织好的、可重复使用的代码块,用于执行特定任务。通过使用函数,可以提高代码的可读性和维护性。在 Python 中,函数通过 `def` 关键字定义,并可以接受参数和返回值。例如: ```python def greet(name): return f"Hello, {name}!" print(greet("Alice")) # 输出: Hello, Alice! ``` ### 变量的作用域 变量的作用域决定了在程序的哪些部分可以访问该变量。Python 中的作用域遵循 LEGB 规则,即 Local(局部)、Enclosing(嵌套)、Global(全局)和 Built-in(内置)的顺序查找变量。 - **Local Scope(局部作用域)**:在函数内部定义的变量具有局部作用域,只能在该函数内访问。 - **Enclosing Scope(嵌套作用域)**:如果一个函数嵌套在另一个函数中,则内部函数可以访问外部函数的变量。 - **Global Scope(全局作用域)**:在模块层级或脚本的最外层定义的变量具有全局作用域,可以在整个模块中访问。 - **Built-in Scope(内置作用域)**:这是 Python 解释器提供的作用域,包含了一些内置函数和变量,如 `print()` 和 `len()`。 ### `global` 和 `nonlocal` 关键词 当需要在函数内部修改全局变量时,可以使用 `global` 关键字来声明该变量为全局变量。例如: ```python x = 10 def update_global(): global x x = 20 update_global() print(x) # 输出: 20 ``` 对于嵌套函数,如果需要修改外部函数的变量,则可以使用 `nonlocal` 关键字。例如: ```python def outer(): y = 10 def inner(): nonlocal y y = 20 inner() print(y) # 输出: 20 outer() ``` ### 闭包(Closures) 闭包是指能够访问并记住其词法作用域的函数,即使该函数在其作用域外执行。闭包通常用于创建工厂函数或保持状态。例如: ```python def make_multiplier(factor): def multiplier(x): return x * factor return multiplier double = make_multiplier(2) print(double(5)) # 输出: 10 ``` ### LEGB 规则 LEGB 规则是 Python 中变量查找的顺序。当在程序中访问一个变量时,Python 会按照以下顺序查找该变量: 1. **Local(局部作用域)**:首先在当前函数中查找变量。 2. **Enclosing(嵌套作用域)**:然后在包含当前函数的任何外部函数中查找变量。 3. **Global(全局作用域)**:接着在模块层级或脚本的最外层查找变量。 4. **Built-in(内置作用域)**:最后在内置作用域中查找变量。 ### 示例代码 以下是一个综合示例,展示了函数、变量作用域、`global` 和 `nonlocal` 关键字以及闭包的使用: ```python # 全局变量 global_var = "global" def outer_function(): # 外部函数变量 outer_var = "outer" def inner_function(): # 内部函数变量 inner_var = "inner" print(f"Inner: {inner_var}, {outer_var}, {global_var}") # 修改外部函数变量 nonlocal outer_var outer_var = "modified outer" # 修改全局变量 global global_var global_var = "modified global" inner_function() print(f"Outer: {outer_var}, {global_var}") outer_function() print(f"Global: {global_var}") ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值