《java编程思想》第10章 内部类

Win11上从零跑通Carla自动驾驶仿真:保姆级环境配置与避坑指南(Python 3.7+) 本文详细介绍了在Win11系统上从零配置Carla自动驾驶仿真环境的完整流程,包括Python 3.7+环境搭建、依赖安装、常见问题排查及性能优化技巧。通过保姆级教程帮助开发者快速避坑,实现稳定的自动驾驶仿真测试环境部署。 阅读详情

内部类:将一个类的定义放在另一个类的定义内部。内部类与组合是完全不同的概念。10.8之后一般用不上。

10.1创建内部类

创建一个内部类:

//: innerclasses/Parcel1.java
// Creating inner classes.

public class Parcel1 {
  class Contents {
    private int i = 11;
    public int value() { return i; }
  }
  class Destination {
    private String label;
    Destination(String whereTo) {
      label = whereTo;
    }
    String readLabel() { return label; }
  }	
  // Using inner classes looks just like
  // using any other class, within Parcel1:
  public void ship(String dest) {
    Contents c = new Contents();
    Destination d = new Destination(dest);
    System.out.println(d.readLabel());
  }
  public static void main(String[] args) {
    Parcel1 p = new Parcel1();
    p.ship("Tasmania");
  }
} /* Output:
Tasmania
*///:~

ship()方法使用内部类,和普通方法一样。

特殊的用处:和上边的代码不同。

//: innerclasses/Parcel2.java
// Returning a reference to an inner class.

public class Parcel2 {
  class Contents {
    private int i = 11;
    public int value() { return i; }
  }
  class Destination {
    private String label;
    Destination(String whereTo) {
      label = whereTo;
    }
    String readLabel() { return label; }
  }
  public Destination to(String s) {
    return new Destination(s);
  }
  public Contents contents() {
    return new Contents();
  }
  public void ship(String dest) {
    Contents c = contents();
    Destination d = to(dest);
    System.out.println(d.readLabel());
  }
  public static void main(String[] args) {
    Parcel2 p = new Parcel2();
    p.ship("Tasmania");
    Parcel2 q = new Parcel2();
    // Defining references to inner classes:
    Parcel2.Contents c = q.contents();
    Parcel2.Destination d = q.to("Borneo");
  }
} /* Output:
Tasmania
*///:~

外部类有一个方法to()和contents(),该方法返回一个指向内部类的引用。

如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,必须指明对象的类型:

OuterClassName.InnerClassName.

10.2链接到外部类

内部类可以访问外围类的所有成员,不需要任何特殊条件。内部类还拥有其外围类的所有元素的访问权限:

//: innerclasses/Sequence.java
// Holds a sequence of Objects.

interface Selector {
  boolean end();
  Object current();
  void next();
}	

public class Sequence {
  private Object[] items;
  private int next = 0;
  public Sequence(int size) { items = new Object[size]; }
  public void add(Object x) {
    if(next < items.length)
      items[next++] = x;
  }
  private class SequenceSelector implements Selector {
    private int i = 0;
    public boolean end() { return i == items.length; }
    public Object current() { return items[i]; }
    public void next() { if(i < items.length) i++; }
  }
//自己注释:该方法返回一个指向内部类的引用
  public Selector selector() {
    return new SequenceSelector();
  }	
  public static void main(String[] args) {
//自己注释:外部类的构造方法
    Sequence sequence = new Sequence(10);
    for(int i = 0; i < 10; i++)
      sequence.add(Integer.toString(i));
//自己注释:创建内部类的对象。
    Selector selector = sequence.selector();
    while(!selector.end()) {
      System.out.print(selector.current() + " ");
      selector.next();
    }
  }
} /* Output:
0 1 2 3 4 5 6 7 8 9
*///:~

SequenceSelector 中的items是外部类的。

内部类的对象只能在与外围类的对象相关联的情况下才能创建(在内部类是非static时)。

10.3使用.this和我.new

需要生成对外部类对象的引用,使用外部类名加this,编译器检查,所以没有开销。

//: innerclasses/DotThis.java
// Qualifying access to the outer-class object.

public class DotThis {
  void f() { System.out.println("DotThis.f()"); }
  public class Inner {
    public DotThis outer() {
      return DotThis.this;
      // A plain "this" would be Inner's "this"
    }
  }
  public Inner inner() { return new Inner(); }
  public static void main(String[] args) {
    DotThis dt = new DotThis();
    DotThis.Inner dti = dt.inner();
    dti.outer().f();
  }
} /* Output:
DotThis.f()
*///:~

new的使用,告诉其他对象,创建某个内部类的对象。需要在new表达式中提供对外部类的引用:

//: innerclasses/DotNew.java
// Creating an inner class directly using the .new syntax.

public class DotNew {
  public class Inner {}
  public static void main(String[] args) {
    DotNew dn = new DotNew();
    DotNew.Inner dni = dn.new Inner();
  }
} ///:~

必须使用外部类对象创建内部类对象。

内部类对象会暗自连接到创建它的外部类上。嵌套类除外,静态内部类。:

//: innerclasses/Parcel3.java
// Using .new to create instances of inner classes.

public class Parcel3 {
  class Contents {
    private int i = 11;
    public int value() { return i; }
  }
  class Destination {
    private String label;
    Destination(String whereTo) { label = whereTo; }
    String readLabel() { return label; }
  }
  public static void main(String[] args) {
    Parcel3 p = new Parcel3();
    // Must use instance of outer class
    // to create an instance of the inner class:
    Parcel3.Contents c = p.new Contents();
    Parcel3.Destination d = p.new Destination("Tasmania");
  }
} ///:~

.new应用于Parcel

10.4内部类与向上转型

当将内部类向上转型为一个基类的时候,尤其是转型为接口的时候。

从实现了某个接口的对象,得到对此接口的引用。

//: innerclasses/Contents.java
public interface Contents {
  int value();
} ///:~
//: innerclasses/Destination.java
public interface Destination {
  String readLabel();
} ///:~

//自己备注:上边是接口


//: innerclasses/TestParcel.java

class Parcel4 {
  private class PContents implements Contents {
    private int i = 11;
    public int value() { return i; }
  }
  protected class PDestination implements Destination {
    private String label;
    private PDestination(String whereTo) {
      label = whereTo;
    }
    public String readLabel() { return label; }
  }
  public Destination destination(String s) {
    return new PDestination(s);
  }
  public Contents contents() {
    return new PContents();
  }
}

public class TestParcel {
  public static void main(String[] args) {
    Parcel4 p = new Parcel4();
    Contents c = p.contents();
    Destination d = p.destination("Tasmania");
    // Illegal -- can't access private class:
    //! Parcel4.PContents pc = p.new PContents();
  }
} ///:~

PContents是private,所以除了Parcel4外没人能访问他。

PDestination 是包访问权限。

10.5在方法和作用域内的内部类

可以在一个方法里面或者任意作用域定义内部类:

实现了某类型的接口,可以创建并返回对其的引用。希望创建一个类解决复杂问题,但是又不想这个类是公共可用的。

方法内部的类,局部内部类:

//: innerclasses/Parcel5.java
// Nesting a class within a method.

public class Parcel5 {
  public Destination destination(String s) {
    class PDestination implements Destination {
      private String label;
      private PDestination(String whereTo) {
        label = whereTo;
      }
      public String readLabel() { return label; }
    }
    return new PDestination(s);
  }
  public static void main(String[] args) {
    Parcel5 p = new Parcel5();
    Destination d = p.destination("Tasmania");
  }
} ///:~

destination方法之外不能方法内部类。return语句向上转型为Destination 。

在任意的作用域中内嵌一个内部类:

//: innerclasses/Parcel6.java
// Nesting a class within a scope.

public class Parcel6 {
  private void internalTracking(boolean b) {
    if(b) {
      class TrackingSlip {
        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");
  }	
  public void track() { internalTracking(true); }
  public static void main(String[] args) {
    Parcel6 p = new Parcel6();
    p.track();
  }
} ///:~

在定义TrackingSlip 这个类之外的作用域这个类不可用,其他与普通类没有任何区别。

10.6匿名内部类

匿名内部类:

//: innerclasses/Parcel7.java
// Returning an instance of an anonymous inner class.

public class Parcel7 {
  public Contents contents() {
    return new Contents() { // Insert a class definition
      private int i = 11;
      public int value() { return i; }
    }; // Semicolon required in this case
  }
  public static void main(String[] args) {
    Parcel7 p = new Parcel7();
    Contents c = p.contents();
  }
} ///:~

contents()方法将返回值的生成与表示这个返回值的类的定义结合在一起!创建一个继承自Contents的匿名类的对象。

上边代码是以下形式的简化形式:

//: innerclasses/Parcel7b.java
// Expanded version of Parcel7.java

public class Parcel7b {
  class MyContents implements Contents {
    private int i = 11;
    public int value() { return i; }
  }
  public Contents contents() { return new MyContents(); }
  public static void main(String[] args) {
    Parcel7b p = new Parcel7b();
    Contents c = p.contents();
  }
} ///:~

上边匿名类使用了默认构造器,以下代码是有参构造器的使用:x

//: innerclasses/Parcel8.java
// Calling the base-class constructor.

public class Parcel8 {
  public Wrapping wrapping(int x) {
    // Base constructor call:
    return new Wrapping(x) { // Pass constructor argument.
      public int value() {
        return super.value() * 47;
      }
    }; // Semicolon required
  }
  public static void main(String[] args) {
    Parcel8 p = new Parcel8();
    Wrapping w = p.wrapping(10);
  }
} ///:~

只需要简单地传递合适的参数给基类的构造器即可,这里是将x传进new Wrapping(x)。

在匿名内部类中定义字段:

//: innerclasses/Parcel9.java
// An anonymous inner class that performs
// initialization. A briefer version of Parcel5.java.

public class Parcel9 {
  // Argument must be final to use inside
  // anonymous inner class:
  public Destination destination(final String dest) {
    return new Destination() {
      private String label = dest;
      public String readLabel() { return label; }
    };
  }
  public static void main(String[] args) {
    Parcel9 p = new Parcel9();
    Destination d = p.destination("Tasmania");
  }
} ///:~

希望匿名内部类使用一个在外部定义的对象,编译器要求其参数引用定义为final。

通过实例初始化,实现为匿名内部类创建一个构造器的效果:

//: innerclasses/AnonymousConstructor.java
// Creating a constructor for an anonymous inner class.
import static net.mindview.util.Print.*;

abstract class Base {
  public Base(int i) {
    print("Base constructor, i = " + i);
  }
  public abstract void f();
}	

public class AnonymousConstructor {
  public static Base getBase(int i) {
    return new Base(i) {
      { print("Inside instance initializer"); }
      public void f() {
        print("In anonymous f()");
      }
    };
  }
  public static void main(String[] args) {
    Base base = getBase(47);
    base.f();
  }
} /* Output:
Base constructor, i = 47
Inside instance initializer
In anonymous f()
*///:~

实例初始化:

//: innerclasses/Parcel10.java
// Using "instance initialization" to perform
// construction on an anonymous inner class.

public class Parcel10 {
  public Destination
  destination(final String dest, final float price) {
    return new Destination() {
      private int cost;
      // Instance initialization for each object:
      {
        cost = Math.round(price);
        if(cost > 100)
          System.out.println("Over budget!");
      }
      private String label = dest;
      public String readLabel() { return label; }
    };
  }	
  public static void main(String[] args) {
    Parcel10 p = new Parcel10();
    Destination d = p.destination("Tasmania", 101.395F);
  }
} /* Output:
Over budget!
*///:~

优先使用类而不是接口:

//: innerclasses/Factories.java
import static net.mindview.util.Print.*;

interface Service {
  void method1();
  void method2();
}

interface ServiceFactory {
  Service getService();
}	

class Implementation1 implements Service {
  private Implementation1() {}
  public void method1() {print("Implementation1 method1");}
  public void method2() {print("Implementation1 method2");}
  public static ServiceFactory factory =
    new ServiceFactory() {
      public Service getService() {
        return new Implementation1();
      }
    };
}	

class Implementation2 implements Service {
  private Implementation2() {}
  public void method1() {print("Implementation2 method1");}
  public void method2() {print("Implementation2 method2");}
  public static ServiceFactory factory =
    new ServiceFactory() {
      public Service getService() {
        return new Implementation2();
      }
    };
}	

public class Factories {
  public static void serviceConsumer(ServiceFactory fact) {
    Service s = fact.getService();
    s.method1();
    s.method2();
  }
  public static void main(String[] args) {
    serviceConsumer(Implementation1.factory);
    // Implementations are completely interchangeable:
    serviceConsumer(Implementation2.factory);
  }
} /* Output:
Implementation1 method1
Implementation1 method2
Implementation2 method1
Implementation2 method2
*///:~
//: innerclasses/Games.java
// Using anonymous inner classes with the Game framework.
import static net.mindview.util.Print.*;

interface Game { boolean move(); }
interface GameFactory { Game getGame(); }

class Checkers implements Game {
  private Checkers() {}
  private int moves = 0;
  private static final int MOVES = 3;
  public boolean move() {
    print("Checkers move " + moves);
    return ++moves != MOVES;
  }
  public static GameFactory factory = new GameFactory() {
    public Game getGame() { return new Checkers(); }
  };
}	

class Chess implements Game {
  private Chess() {}
  private int moves = 0;
  private static final int MOVES = 4;
  public boolean move() {
    print("Chess move " + moves);
    return ++moves != MOVES;
  }
  public static GameFactory factory = new GameFactory() {
    public Game getGame() { return new Chess(); }
  };
}	

public class Games {
  public static void playGame(GameFactory factory) {
    Game s = factory.getGame();
    while(s.move())
      ;
  }
  public static void main(String[] args) {
    playGame(Checkers.factory);
    playGame(Chess.factory);
  }
} /* Output:
Checkers move 0
Checkers move 1
Checkers move 2
Chess move 0
Chess move 1
Chess move 2
Chess move 3
*///:~

10.7嵌套类

嵌套类:不需要内部类对象于其外围类对象之间有联系,将内部类声明为static。

创建嵌套类对象并不需要其外围类的对象。

不能从嵌套类的对象中访问非静态的外围类。

嵌套类:

//: innerclasses/Parcel11.java
// Nested classes (static inner classes).

public class Parcel11 {
  private static class ParcelContents implements Contents {
    private int i = 11;
    public int value() { return i; }
  }
  protected static class ParcelDestination
  implements Destination {
    private String label;
    private ParcelDestination(String whereTo) {
      label = whereTo;
    }
    public String readLabel() { return label; }	
    // Nested classes can contain other static elements:
    public static void f() {}
    static int x = 10;
    static class AnotherLevel {
      public static void f() {}
      static int x = 10;
    }
  }
  public static Destination destination(String s) {
    return new ParcelDestination(s);
  }
  public static Contents contents() {
    return new ParcelContents();
  }
  public static void main(String[] args) {
    Contents c = contents();
    Destination d = destination("Tasmania");
  }
} ///:~

在main方法中,没有任何Parcel11对象是必须的。

接口内部的类,接口的内部类默认public static ,可以实现外围接口的:

//: innerclasses/ClassInInterface.java
// {main: ClassInInterface$Test}

public interface ClassInInterface {
  void howdy();
  class Test implements ClassInInterface {
    public void howdy() {
      System.out.println("Howdy!");
    }
    public static void main(String[] args) {
      new Test().howdy();
    }
  }
} /* Output:
Howdy!
*///:~

想要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用,可以使用接口内部的嵌套类。

可以使用嵌套类放置main测试代码:

//: innerclasses/TestBed.java
// Putting test code in a nested class.
// {main: TestBed$Tester}

public class TestBed {
  public void f() { System.out.println("f()"); }
  public static class Tester {
    public static void main(String[] args) {
      TestBed t = new TestBed();
      t.f();
    }
  }
} /* Output:
f()
*///:~

一个内部类无论被嵌套多少层,都能透明的访问所有它所嵌入的外围类的所有成员。

10.8为什么需要内部类

内部类一般继承自某个类或者实现某个接口,内部类的代码操作创建它的外围类的对象,所以可以认为内部类提供了某种进入其外围类的窗口。

每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现。对于内部类都没有影响。内部类使得多重继承解决方案变得完整。

单一类和内部类:

//: innerclasses/MultiInterfaces.java
// Two ways that a class can implement multiple interfaces.
package innerclasses;

interface A {}
interface B {}

class X implements A, B {}

class Y implements A {
  B makeB() {
    // Anonymous inner class:
    return new B() {};
  }
}

public class MultiInterfaces {
  static void takesA(A a) {}
  static void takesB(B b) {}
  public static void main(String[] args) {
    X x = new X();
    Y y = new Y();
    takesA(x);
    takesA(y);
    takesB(x);
    takesB(y.makeB());
  }
} ///:~

内部类实现多重继承:

//: innerclasses/MultiImplementation.java
// With concrete or abstract classes, inner
// classes are the only way to produce the effect
// of "multiple implementation inheritance."
package innerclasses;

class D {}
abstract class E {}

class Z extends D {
  E makeE() { return new E() {}; }
}

public class MultiImplementation {
  static void takesD(D d) {}
  static void takesE(E e) {}
  public static void main(String[] args) {
    Z z = new Z();
    takesD(z);
    takesE(z.makeE());
  }
} ///:~

闭包:是一个可调用的对象,它记录一些信息,这些信息来自于创建它的作用域。内部类是面向对象的闭包。

回调:对象能够携带一些信息,这些信息允许它在稍后的某个时刻调用初始的对象。

内部类提供闭包:

//: innerclasses/Callbacks.java
// Using inner classes for callbacks
package innerclasses;
import static net.mindview.util.Print.*;

interface Incrementable {
  void increment();
}

// Very simple to just implement the interface:
class Callee1 implements Incrementable {
  private int i = 0;
  public void increment() {
    i++;
    print(i);
  }
}	

class MyIncrement {
  public void increment() { print("Other operation"); }
  static void f(MyIncrement mi) { mi.increment(); }
}	

// If your class must implement increment() in
// some other way, you must use an inner class:
class Callee2 extends MyIncrement {
  private int i = 0;
  public void increment() {
    super.increment();
    i++;
    print(i);
  }
  private class Closure implements Incrementable {
    public void increment() {
      // Specify outer-class method, otherwise
      // you'd get an infinite recursion:
      Callee2.this.increment();
    }
  }
  Incrementable getCallbackReference() {
    return new Closure();
  }
}	

class Caller {
  private Incrementable callbackReference;
  Caller(Incrementable cbh) { callbackReference = cbh; }
  void go() { callbackReference.increment(); }
}

public class Callbacks {
  public static void main(String[] args) {
    Callee1 c1 = new Callee1();
    Callee2 c2 = new Callee2();
    MyIncrement.f(c2);
    Caller caller1 = new Caller(c1);
    Caller caller2 = new Caller(c2.getCallbackReference());
    caller1.go();
    caller1.go();
    caller2.go();
    caller2.go();
  }	
} /* Output:
Other operation
1
1
2
Other operation
2
Other operation
3
*///:~

内部类与控制框架,接口描述了要控制的事件:

//: innerclasses/controller/Event.java
// The common methods for any control event.
package innerclasses.controller;

public abstract class Event {
  private long eventTime;
  protected final long delayTime;
  public Event(long delayTime) {
    this.delayTime = delayTime;
    start();
  }
  public void start() { // Allows restarting
    eventTime = System.nanoTime() + delayTime;
  }
  public boolean ready() {
    return System.nanoTime() >= eventTime;
  }
  public abstract void action();
} ///:~
//: innerclasses/controller/Controller.java
// The reusable framework for control systems.
package innerclasses.controller;
import java.util.*;

public class Controller {
  // A class from java.util to hold Event objects:
  private List<Event> eventList = new ArrayList<Event>();
  public void addEvent(Event c) { eventList.add(c); }
  public void run() {
    while(eventList.size() > 0)
      // Make a copy so you're not modifying the list
      // while you're selecting the elements in it:
      for(Event e : new ArrayList<Event>(eventList))
        if(e.ready()) {
          System.out.println(e);
          e.action();
          eventList.remove(e);
        }
  }
} ///:~

典型的应用框架:

//: innerclasses/GreenhouseControls.java
// This produces a specific application of the
// control system, all in a single class. Inner
// classes allow you to encapsulate different
// functionality for each type of event.
import innerclasses.controller.*;

public class GreenhouseControls extends Controller {
  private boolean light = false;
  public class LightOn extends Event {
    public LightOn(long delayTime) { super(delayTime); }
    public void action() {
      // Put hardware control code here to
      // physically turn on the light.
      light = true;
    }
    public String toString() { return "Light is on"; }
  }	
  public class LightOff extends Event {
    public LightOff(long delayTime) { super(delayTime); }
    public void action() {
      // Put hardware control code here to
      // physically turn off the light.
      light = false;
    }
    public String toString() { return "Light is off"; }
  }
  private boolean water = false;
  public class WaterOn extends Event {
    public WaterOn(long delayTime) { super(delayTime); }
    public void action() {
      // Put hardware control code here.
      water = true;
    }
    public String toString() {
      return "Greenhouse water is on";
    }
  }	
  public class WaterOff extends Event {
    public WaterOff(long delayTime) { super(delayTime); }
    public void action() {
      // Put hardware control code here.
      water = false;
    }
    public String toString() {
      return "Greenhouse water is off";
    }
  }
  private String thermostat = "Day";	
  public class ThermostatNight extends Event {
    public ThermostatNight(long delayTime) {
      super(delayTime);
    }
    public void action() {
      // Put hardware control code here.
      thermostat = "Night";
    }
    public String toString() {
      return "Thermostat on night setting";
    }
  }	
  public class ThermostatDay extends Event {
    public ThermostatDay(long delayTime) {
      super(delayTime);
    }
    public void action() {
      // Put hardware control code here.
      thermostat = "Day";
    }
    public String toString() {
      return "Thermostat on day setting";
    }
  }
  // An example of an action() that inserts a
  // new one of itself into the event list:
  public class Bell extends Event {
    public Bell(long delayTime) { super(delayTime); }
    public void action() {
      addEvent(new Bell(delayTime));
    }
    public String toString() { return "Bing!"; }
  }	
  public class Restart extends Event {
    private Event[] eventList;
    public Restart(long delayTime, Event[] eventList) {
      super(delayTime);
      this.eventList = eventList;
      for(Event e : eventList)
        addEvent(e);
    }
    public void action() {
      for(Event e : eventList) {
        e.start(); // Rerun each event
        addEvent(e);
      }
      start(); // Rerun this Event
      addEvent(this);
    }
    public String toString() {
      return "Restarting system";
    }
  }	
  public static class Terminate extends Event {
    public Terminate(long delayTime) { super(delayTime); }
    public void action() { System.exit(0); }
    public String toString() { return "Terminating";  }
  }
} ///:~

命令模式例子:

//: innerclasses/GreenhouseController.java
// Configure and execute the greenhouse system.
// {Args: 5000}
import innerclasses.controller.*;

public class GreenhouseController {
  public static void main(String[] args) {
    GreenhouseControls gc = new GreenhouseControls();
    // Instead of hard-wiring, you could parse
    // configuration information from a text file here:
    gc.addEvent(gc.new Bell(900));
    Event[] eventList = {
      gc.new ThermostatNight(0),
      gc.new LightOn(200),
      gc.new LightOff(400),
      gc.new WaterOn(600),
      gc.new WaterOff(800),
      gc.new ThermostatDay(1400)
    };	
    gc.addEvent(gc.new Restart(2000, eventList));
    if(args.length == 1)
      gc.addEvent(
        new GreenhouseControls.Terminate(
          new Integer(args[0])));
    gc.run();
  }
} /* Output:
Bing!
Thermostat on night setting
Light is on
Light is off
Greenhouse water is on
Greenhouse water is off
Thermostat on day setting
Restarting system
Terminating
*///:~

10.9内部类的继承

因为内部类的构造器必须连接到指向其外围类对象的引用。

//: innerclasses/InheritInner.java
// Inheriting an inner class.

class WithInner {
  class Inner {}
}

public class InheritInner extends WithInner.Inner {
  //! InheritInner() {} // Won't compile
  InheritInner(WithInner wi) {
    wi.super();
  }
  public static void main(String[] args) {
    WithInner wi = new WithInner();
    InheritInner ii = new InheritInner(wi);
  }
} ///:~

10.10内部类可以被覆盖吗

//: innerclasses/BigEgg.java
// An inner class cannot be overriden like a method.
import static net.mindview.util.Print.*;

class Egg {
  private Yolk y;
  protected class Yolk {
    public Yolk() { print("Egg.Yolk()"); }
  }
  public Egg() {
    print("New Egg()");
    y = new Yolk();
  }
}	

public class BigEgg extends Egg {
  public class Yolk {
    public Yolk() { print("BigEgg.Yolk()"); }
  }
  public static void main(String[] args) {
    new BigEgg();
  }
} /* Output:
New Egg()
Egg.Yolk()
*///:~

当继承了某个外围类的时候,内部类并没有发生什么变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内:

//: innerclasses/BigEgg2.java
// Proper inheritance of an inner class.
import static net.mindview.util.Print.*;

class Egg2 {
  protected class Yolk {
    public Yolk() { print("Egg2.Yolk()"); }
    public void f() { print("Egg2.Yolk.f()");}
  }
  private Yolk y = new Yolk();
  public Egg2() { print("New Egg2()"); }
  public void insertYolk(Yolk yy) { y = yy; }
  public void g() { y.f(); }
}	

public class BigEgg2 extends Egg2 {
  public class Yolk extends Egg2.Yolk {
    public Yolk() { print("BigEgg2.Yolk()"); }
    public void f() { print("BigEgg2.Yolk.f()"); }
  }
  public BigEgg2() { insertYolk(new Yolk()); }
  public static void main(String[] args) {
    Egg2 e2 = new BigEgg2();
    e2.g();
  }
} /* Output:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
*///:~

 

10.11局部内部类

//: innerclasses/LocalInnerClass.java
// Holds a sequence of Objects.
import static net.mindview.util.Print.*;

interface Counter {
  int next();
}	

public class LocalInnerClass {
  private int count = 0;
  Counter getCounter(final String name) {
    // A local inner class:
    class LocalCounter implements Counter {
      public LocalCounter() {
        // Local inner class can have a constructor
        print("LocalCounter()");
      }
      public int next() {
        printnb(name); // Access local final
        return count++;
      }
    }
    return new LocalCounter();
  }	
  // The same thing with an anonymous inner class:
  Counter getCounter2(final String name) {
    return new Counter() {
      // Anonymous inner class cannot have a named
      // constructor, only an instance initializer:
      {
        print("Counter()");
      }
      public int next() {
        printnb(name); // Access local final
        return count++;
      }
    };
  }	
  public static void main(String[] args) {
    LocalInnerClass lic = new LocalInnerClass();
    Counter
      c1 = lic.getCounter("Local inner "),
      c2 = lic.getCounter2("Anonymous inner ");
    for(int i = 0; i < 5; i++)
      print(c1.next());
    for(int i = 0; i < 5; i++)
      print(c2.next());
  }
} /* Output:
LocalCounter()
Counter()
Local inner 0
Local inner 1
Local inner 2
Local inner 3
Local inner 4
Anonymous inner 5
Anonymous inner 6
Anonymous inner 7
Anonymous inner 8
Anonymous inner 9
*///:~

匿名内部类只能用实例初始化。

10.12内部类标识符

Java的每个类都会产生一个class文件,所以内部类也会,包括匿名内部类。

外围类名字$内部类名字.class

外围类名字$1.class      //匿名内部类

10.13总结

在设计阶段考虑使用接口或者内部类。

[漏洞利用]利用五次Shift越权破解win7\win10开机密码 注:第一个学习和接触的Windows漏洞 文章目录本机实验环境前置知识漏洞原理漏洞介绍漏洞验证解决方法基本流程介绍详细步骤截图 本机实验环境 虚拟机:VMware Workstation 14 pro 操作系统:Windows10 前置知识 1、cmd工具路径 c:\windows\system32\cmd,按五次shift默认调用同目录下sethc文件,其路径为“c:\windows\system32\sethc.exe” 2、用户/账户密码存储位置 c:\windows\system32\config\ 阅读详情

相关推荐

告别手动画图!用Cadence SKILL写一个参数化电感PCell(附完整代码)

本文详细介绍了如何使用Cadence SKILL语言开发参数化电感PCell,实现电感版图的自动化生成。通过动态调整线宽、圈数等几何参数,自动创建端口并进行工艺规则校验,大幅提升高频电路设计效率。附完整代码示例,帮助工程师快速掌握PCell开发技巧。

weixin_30684743的博客 366

面试题(一)JVM常见面试题

JVM 面试题 一.Java 类加载过程? Java 类加载需要经历一下 7 个过程: 1. 加载 加载是类加载的第一个过程,在这个阶段,将完成一下三件事情: • 通过一个类的全限定名获取该类的二进制流。 • 将该二进制流中的静态存储结构转化为方法去运行时数据结 构。 • 在内存中生成该类的 Class 对象,作为该类的数据访问入口。 2. 验证 验证的目的是为了确保 Class 文件的字节流中的信息不回危害到 虚拟机.在该阶段主要完成以下四钟验证:

liuerchong的博客 352

用ESP32和HomeSpan自制HomeKit智能灯,手把手教你从零接入苹果家庭App

本文详细介绍了如何使用ESP32开发板和HomeSpan开源库自制原生HomeKit智能灯,从硬件搭建到软件配置,再到通过苹果家庭App控制的全过程。项目绕过了苹果MFi认证,成本低廉但功能完整,支持Siri语音控制、自动化场景等高级功能,是智能家居DIY的实用指南。

weixin_28717431的博客 321

java中会存在内存泄漏吗 请简单描述_Java 中会存在内存泄漏吗,请简单描述

内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说,Java是有GC垃圾回收机制的,也就是说,不再被使用的对象,会被GC自动回收掉,自动从内存中清除。但是,即使这样,Java也还是存在着内存泄漏的情况,1、长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露。尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是Java中内存泄露的发生场...

weixin_29738537的博客 636

Keil5安装教程(保姆级)Keil5mdk安装步骤

6、复制生成的激活码,粘贴在New License ID Code处,点击Add LIC,即可成功激活mdk,显示mdk的使用期限。6、复制生成的激活码,粘贴在New License ID Code处,点击Add LIC,即可成功激活C51,显示mdk的使用期限;3、在安装文件中点击keygen.exe文件,粘贴复制过的CID,选择Target为C51,点击Generate,生成激活码;4、在弹出的界面中会自动安装在安装keil的路径,点击“Next”进行后续安装,安装完成后,点击“Finish”。

m6886258的博客 9万+

基于 SpringAI 整合 DeepSeek 模型实现 AI 聊天对话

很多云平台都提供了一键部署大模型的功能,这里不再赘述(阿里云百炼平台、火山方舟-火山引擎等)Ollama。

📜一个热爱探索的人 1277

什么是内存溢出以及java中内存泄漏5种情况的总结

内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间。      一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。内存溢出 out of memory :指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢...

lzh_86的博客 1819

【国产化信创实践】宝兰德bes中间件集成springboot

【国产化信创实践】宝兰德bes中间件集成springboot

项目管理、软件工厂、vue研发、Java研发、中国文化等。 1万+

java面试题

java中会存在内存泄漏吗,请简单描述。 所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如 ja

yin_shuzhen的博客 415

手把手教你离线部署bert-base-uncased模型(附完整文件清单)

本文提供了一份详尽的bert-base-uncased模型离线部署指南。针对严格内网或无网络环境,文章不仅列出了包括config.json、pytorch_model.bin在内的完整必需文件清单,还详细解释了每个文件的作用,并给出了使用snapshot_download工具或手动下载的两种文件获取方法。重点阐述了如何正确设置本地路径、编写健壮的加载代码,并通过多层次验证确保模型在离线环境下成功运行,有效解决了部署过程中常见的文件缺失和路径错误问题。

weixin_29034963的博客 320

037、有源钳位反激变换器(ACF)原理

文章摘要 有源钳位反激变换器(ACF)是一种克服常规反激电路漏感能量处理瓶颈的高效解决方案。文章从实际炸机案例切入,指出RCD钳位电路在高压、宽范围、高功率场景下的局限性。ACF通过增加钳位管和钳位电容,将漏感能量回收而非消耗,实现效率提升2-3%、精准电压钳位和更好EMI性能。文章详细解析了ACF四阶段工作过程、关键波形特征,并指出设计陷阱:漏感需保持1%-3%特定范围、钳位电容ESR要求严格、需专用控制IC支持互补驱动。最后给出实用调试建议,强调ACF适用于65W+功率场景,低压验证后再逐步升压的调试方

Jack010169的博客 256

java基础面试题(三)

21、描述一下JVM加载class文件的原理机制?22、char 型变量中能不能存贮一个中文汉字,为什么?23、抽象类(abstract class)和接口(interface)有什么异同?24、静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?25、Java 中会存在内存泄漏吗,请简单描述。26、抽象的(abstract)方法是否可同时是静态的(sta...

Mr.Xie的博客 479

使用epiDisplay包中的logistic

其中的logistic.display函数可以用于获取逻辑回归模型的汇总统计信息,包括自变量的优势比和置信区间,以及回归系数的Wald检验的p值。最后,我们使用print函数打印出汇总统计信息。使用epiDisplay包中的logistic.display函数获取逻辑回归模型的汇总统计信息(包括自变量的初始和调整后的优势比及置信区间,回归系数的Wald检验的p值)- R语言。通过使用logistic.display函数,我们可以方便地获取逻辑回归模型的重要统计信息,并对自变量的影响进行解释和推断。

CyberJolt的博客 608

《JAVA编程思想》学习笔记:第10章(内部类)

目录Java编程思想(一)第1~4章:概述Java编程思想(二)第5章:初始化和清理Java编程思想(三)第6章:访问权限Java编程思想(四)第7章:复用类Java编程思想(五)第8章:多态Java编程思想(六)第9章:接口Java编程思想(七)第10章:内部类Java编程思想(八)第11章:持有对象Java编程思想(九)第12章:异常Java编程思想(十)第13章:字符串Java编程思想(十一...

caobaokang的专栏 4743

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

第10章 内部类(java编程思想)

10.1 创建内部类 典型的应用情况是,外部类将会有一个方法,该方法返回以内部类的引用。就像在to()和content()中看到的那样。 //: innerclasses/Parcel2.java // Returning a reference to an inner class. public class Parcel2 { class Contents { private int i = 11; public int value() { return i; } } cla

printf_myself的博客 133

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java编程思想 第10章 内部类 笔记

如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么就必须像在main()方法中那样,具体地指明这个对象的类型:OuterClassName.InnerClassName。当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问 其外围对象的所有成员,而不需要任何特殊条件。要想直接创建内部类的对象,必须使用外部类的对象来创建内部类对象。如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。在拥有外部类对象之前是不可能创建内部类对象的。

weixin_42199601的博客 136

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

java编程思想_第10章_内部类

1.内部类可以直接调用外部类的成员属性以及方法,但是外部类不可以直接调用内部类的成员属性以及方法,必须通过对象形式调用。 2.在拥有外部类的对象之前是不能创建内部类对象的,因为内部类可能会连接到外部类的对象上;但如果创建的是静态内部类就可以直接创建内部类对象。 3.内部类创建对象方式:1)创建外部类对象,在外部类中用一个方法返回内部类对象                           ...

ycllycll的博客 248

Java编程思想 第10章 内部类

Java编程思想 第10章 内部类 标签(空格分隔): JAVA学习 可以将一个类的定义放在另一个类的定义内部,这就是内部类。 10.1 创建内部类 public class Parcell { class Contents { private int i = 11; public int value() { r...

当初游的快了一点 432

《Java编程思想》读书笔记 —— 第10章 内部类

内部类的定义可以从字面上理解,即一个定义在一个类内部的类,基本上就是“套娃”的意思,和前面一章所提到的嵌套接口其实是差不多的东西,但是语法上要比嵌套接口复杂很多。内部类的特点是允许程序员把逻辑相关的类组织在一起,前一章的简介部分也提到,内部类和接口都是使接口和实现方法分离的结构化方法。 就我的个人体验看来,内部类的语法相较于前面的内容确实是比较复杂的,语法点有点多,上个暑假读过一遍之后现在脑袋中的...

banqinghe的博客 247

JAVA 编程思想第10章--内部类概要

1 内部类可以访问外部内所有成员,无访问权限的限制 2 内部类对象实例化必须依赖外部类的实例,静态内部类无需依赖 3 不能直接引用外部类名称来实例化内部类 4 外部类A不能访问类B的private内部类 5 局部内部类---方法里的内部类

xuxinyl的博客 378

【笔记】《Java编程思想(第四版)》第10章-内部类

第10章 内部类 可以将一个类定义放在另一个类的定义内部,这就是内部类。 在最初,内部类看起来就像是一种代码隐藏机制:将类置于其他类的内部。但是,你将会了解到,内部类远不止如此,它了解外围类,并能与之通信;而且你用内部类写出的代码更加优雅而清晰,尽管并不总是这样。 10.1 创建内部类 创建内部类的方式就如同你想的一样——把类的定义置于外围类的里面。 //:innerclasses/Parcel1...

ZeromaXHe的博客 553

《JAVA编程思想》阅读笔记 第10章 内部类

在外部类的非静态方法中使用内部类时,用法与普通类的使用方式相同,但是在其余的任意地方创建内部类对象时,就必须用 OuterClassName.InnerClassName 的方式进行声明。 内部类能够访问外部类的所有元素,而且其对象能够访问外部类对象的所有成员。 ...

搬砖咸鱼 208

java编程思想第10章内部类 总结(1)

一、内部类的定义:将一个类的定义放在另外一个类的定义内部 10.1.创建内部类 a.一个基本的内部类的代码编写 10.2链接到外部类 a.内部类可以范文外部类的的成员 10.3使用.this与new a.当前类的的对象的引用使用 类名.this b.创建内部类,采用(外部类.内部类  变量= 外部类的引用.new  内部类名) 10.4内部类与向上转型 a.可以采用内部类的方式实

xiaocao000o的博客 272

Java编程思想阅读笔记(第10章内部类)

内部类 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的 可以将一个类的定义放在另一个类定义内部,这就是内部类 内部类自动拥有对包裹它的基类所有成员的访问权限 内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限) 内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类 内...

u010391342的博客 220

[学习笔记][Java编程思想]第10章:内部类

内部类允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。 1 创建内部类 创建内部类的方式是把类的定义置于外围类的里面。 外部类可以有一个方法,该方法返回一个指向内部类的引用。 从外部类的非静态方法之外的任意位置创建某个内部类的对象,需要具体地指明这个对象的类型:OuterClassName.InnerClassName。 2 链接到外部类 内部类还拥有其外围类的所有元素的访问权。 内

lbt_never的博客 419

Java编程思想,读书笔记八(第10章 内部类)

      第10章 内部类      可以将一个类的定义放到另一个类的定义内部,这就是内部类。内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。然而必须要了解,内部类和组合是完全不同的概念。在最初,内部类看起来像是一种代码隐藏机制:将类置于其他类的内部。但是,你将会了解到,内部类远不止如此,它了解外部类,并能与之通信;而且你用内部类写出的代码更加优...

闫玉林的博客 477
上一篇: 《java编程思想》第七章 复用类
下一篇: LeetCode-627. 交换工资( 627. Swap Salary)。知识点:UPDATE and CASE...WHEN 和 if
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值