• 第10章 内部类


    • 内部类:在类中定义的类,外层的叫外部类、外围类。
    • 书中说P191,如果想在外部类的非静态方法之外的任意位置创建某个内部类对象,那么必须像在main方法(静态方法)中那样,具体地指明这个对象的类型:OuterClassName.InnerClassName。(在外部类非静态方法中可以直接使用InnerClassName)
    • 书上(10.2)的例子,说在内部类,可以直接访问其外围类的所有成员(方法和字段),就像内部类自己拥有它们似的,这带来了很大的便利。(但是在main函数(外围类的static函数)中,内部类的对象不能访问外部类的成员)
    • 内部类自动拥有对其外围类所有成员的访问权p192。这是如何做到的呢?当某个外围类的对象创建了一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。然后,
    •  迭代器设计模式p192:外围类存数据,并且存在产生内部类对象的方法,私有内部类实现Selector接口以作为迭代器访问数据。
    • 使用"OuterClassName.this"p193):书上说有时候,需要在内部类的中,生成包含它的外部类对象的引用,可以使用此语法
     1 public class DotThis {
     2 
     3 void f() {
     4 
     5 System.out.println("DotThis.f()");
     6 
     7 }
     8 
     9 public class Inner {
    10 
    11 public DotThis outer() {
    12 
    13 f();
    14 
    15 return DotThis.this;
    16 
    17 // A plain "this" would be Inner's "this"
    18 
    19 }
    20 
    21 }
    22 
    23 public Inner inner() {
    24 
    25 return new Inner();
    26 
    27 }
    28 
    29 public static void main(String[] args) {
    30 
    31 DotThis dt = new DotThis();
    32 
    33 DotThis.Inner dti = dt.inner();
    34 
    35 dti.outer().f();
    36 
    37 }
    38 
    39 } /*
    40 
    41  * Output: DotThis.f()
    42 
    43  */// :~
    View Code
    • 使用“OuterClass对象的引用.new”:创建内部类对象,必须先指明外部类对象的引用,而不是"new OuterClassName.InnerClassName();"。

    Eg:

     1 public class DotNew {
     2 
     3   public class Inner {
     4 
     5   public Inner(){
     6 
     7   System.out.println("Inner class constructor.");
     8 
     9   }
    10 
    11   }
    12 
    13   public static void main(String[] args) {
    14 
    15     DotNew dn = new DotNew();
    16 
    17     DotNew.Inner dni = dn.new Inner();     //dn已经指明外部类,故不需(也不能)dn.new DotNew.Inner();
    18 
    19     //!DotNew.Inner dni2 = new DotNew.Inner();
    20 
    21   }
    22 
    23 } ///:~
    View Code
    • 匿名内部类(p197):在函数内部定义类的一种方式,不显示定义类名,一次性使用。一般有父类、父接口。在定义的地方之外,也能使用匿名内部类的函数。匿名内部类定义结束分好分隔。
    • 静态函数用作类似于构造函数的功能(p198),静态函数里面有一段代码实现实例初始化功能。
    • 书上(198-199)说:包含匿名内部类的函数,参数如果会在匿名内部类内部被使用个,则必须是final的;(但是实际使用的时候,去掉final也不见报错)
    • 实例初始化:什么是”实例初始化“? 匿名内部类由于类名被省略,故没有构造函数,用”实例初始化“功能来代替构造函数,书上例子Parcel10.java所示,实现”实例初始化“功能的代码必须要被大括号围住。
    • 匿名内部类既可以扩展类,也可以实现接口,但是两者不可以同时兼备。而且不能实现多个接口。
    •  使用“匿名内部类”的“工厂方法设计模式”改写interfaces/Games.java
     1 package exercise;
     2 import static net.mindview.util.Print.*;
     3 
     4 interface Game {
     5     boolean move();
     6 }
     7 
     8 interface GameFactory {
     9     Game getGame();
    10 }
    11 
    12 class Checkers implements Game{
    13     private int moves = 0;
    14     private static final int MOVES = 3;
    15     public boolean move(){
    16         print("Checkers move " + moves);
    17         return ++moves != MOVES;
    18     }
    19     public static GameFactory factory = new GameFactory(){
    20         public Game getGame(){
    21             return new Checkers();
    22         }
    23     };
    24 }
    25 
    26 
    27 public class Common {
    28     
    29     public static void serviceConsumer(GameFactory fact){
    30         Game g = fact.getGame();
    31         while(g.move());
    32     }
    33     
    34     public static void main(String[] args) {
    35         serviceConsumer(Checkers.factory);
    36     }
    37 
    38 }
    View Code
  • 相关阅读:
    使用Lazy对构造进行重构后比较
    Ninject Lazy Load
    在 MVC 中使用 ninject Lazy Load的一个想法
    在Ninject 向构造参数中注入具有相同类型的参数
    关于 SimpleMembership 中 CreateDate 的问题
    ubuntu下谷歌浏览器字体模糊解决方案
    ubuntu双系统时间错乱
    WPS for Linux字体配置(Ubuntu 16.04)
    VS常见错误
    VMware虚拟机ubuntu显示屏幕太小解决办法
  • 原文地址:https://www.cnblogs.com/HITSZ/p/6411300.html
Copyright © 2020-2023  润新知