1. 内部类的特性

  • 他允许你把一些逻辑相关的类组织在一起。

2. 使用.this

  • 如果你需要在内部类中堆外部类进行应用,可以使用外部类的名字后面加.this。下面展示了如何使用 .this

    package net.mindview.innerclasses;
    
    public class DotThis {
    void f(){
    System.out.println("DotThis.f()");
    } public class Inner {
    public DotThis outer() {
    System.out.println(DotThis.this);
    return DotThis.this;
    }
    } public Inner inner(){
    return new Inner();
    } public static void main(String[] args) {
    DotThis dt = new DotThis();
    DotThis.Inner di = dt.inner();
    di.outer().f();
    } }

3.使用.new

  • 如果想要创建某个外部类的内部类,可以使用外部类对象.new 内部类:
  • 如果想new一个内部类, 不能使用外部类.new 内部类。必须使用外部类的对象来创建内部类的对象。    用法如下:
    package net.mindview.innerclasses;
    
    public class DotNew {
    
        public class Inner {
    
        }
    public static void main(String[] args) {
    DotNew dn = new DotNew();
    DotNew.Inner di = dn.new Inner();
    }
    }

4. 方法的内部类

  • 这里只说两点:

    • 方法的内部类有效作用域是在方法内,方法外部可以调用
    • 方法的内部类,并不是说方法被调用的时候才创建了,实际上,这个类和其他类没有什么不同,他们在使用之前,已经经过编译了.
      package net.mindview.innerclasses;
      
      /**
      * 方法内部类的作用域就在方法内,方法外不可以访问.
      * @author samsung
      *
      */
      public class Parcel5 {
      public Destination destination(String s){
      //在方法里定义了一个内部类
      class PDestination implements Destination{
      private String label;
      public PDestination(String label){
      System.out.println(this);
      this.label = label;
      }
      @Override
      public String readLabel() {
      return label;
      }
      } return new PDestination(s);
      }
      public static void main(String[] args) {
      Parcel5 p = new Parcel5();
      System.out.println(p.destination("上海").readLabel());
      System.out.println(p.destination("北京").readLabel());
      } /**
      * 注意:PDestination定义在方法里面,并不是说只有调用方法的时候,这个类才被创建.
      * 实际上,这个类和其他类一样,已经经过编译了.
      */
      }

5. 定义在作用域内的内部类, 此作用域在方法的内部.

  • 定义在方法作用域内部的类, 只在作用域内部有效
package net.mindview.innerclasses;

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("");
String s = ts.getSlip();
}
//作用域外不可使用
//TrackingSlip ts = new TrackingSlip("100");
} public void track(){
internalTracking(true);
} public static void main(String[] args) {
Parcel6 p = new Parcel6();
p.track();
}
}

6.匿名内部类

  • 默认构造器匿名内部类

    package net.mindview.innerclasses;
    
    public class Parcel7 {
    public Contents contents(){
    //定义了一个匿名内部类.将返回值和创建类放在了一起
    return new Contents(){
    private int i = ;
    @Override
    public int value() {
    return i;
    }
    };
    }
    public static void main(String[] args) {
    Parcel7 p = new Parcel7();
    Contents c = p.contents();
    System.out.println(c.value()); } }
  • 代参数构造器的匿名内部类
    package net.mindview.innerclasses;
    
    public class Wrapping {
    
        private int i;
    public Wrapping(int x){
    this.i = x;
    }
    public int value(){
    return i;
    }
    }
    package net.mindview.innerclasses;
    
    public class Parcel8 {
    public Wrapping wrapping(int x){
    return new Wrapping(x){
    @Override
    public int value(){
    return super.value()*;
    }
    };
    } public static void main(String[] args) {
    Parcel8 p = new Parcel8();
    Wrapping w = p.wrapping();
    System.out.println(w.value());
    } }

    这里需要注意的是, 虽然Wrapping是一个导出类, 却依然被当成了一个接口来使用.

  • 匿名内部类中使用外部对象, 这外部的这个对象必须是final的
    package net.mindview.innerclasses;
    
    public class Parcel9 {
    public Destination destination(final String x){
    final String m = null;
    //匿名内部类
    return new Destination(){
    //在内部类中使用到了外部的对象
    private String label = m;
    private String abc = x;
    @Override
    public String readLabel() {
    return label;
    }
    };
    }
    public static void main(String[] args) {
    Parcel9 p = new Parcel9();
    System.out.println(p.destination("").readLabel());
    } /**
    * 定义一个匿名内部类, 如果希望在匿名内部类中使用外部的对象,
    * 那么编译器要求外部类的这个参数必须是final的. 如果你没有将这个类定义为final
    * 编译器会报错
    */ }
  • 在匿名内部类中使用类似构造器的行为. 我们知道匿名内部类没有类名, 因此他不可能有命名构造器. 但通过实例初始化可,就鞥够达到为匿名内部类创建一个构造器的效果
    package net.mindview.innerclasses;
    
    abstract class Base{
    public Base(int i){
    System.out.println("Base构造器, i=" + i);
    } public abstract void f();
    }
    public class AnonymousConstructor {
    /**
    * 此处的i不要求是final的,因为这个i只是传递给了匿名
    * 变量的构造器,并没有在匿名内部类内部使用.
    */
    public static Base getBase(int i){
    return new Base(i){
    {
    System.out.println("这里可以类似构造器进行初始化");
    }
    @Override
    public void f() {
    System.out.println("匿名函数f()");
    } };
    }
    public static void main(String[] args) {
    AnonymousConstructor amc = new AnonymousConstructor();
    amc.getBase().f();
    } }

7. 再谈工厂设计模式.

  再上一章中说了工厂设计模式. 本书中的案例是对象工厂设计模式. 来看看是怎么写的

package net.mindview.innerclasses.factory.MethodFactory;
/**
* 服务类
*/
interface Service{
void method1();
void method2();
} /**
* 工厂类
*/
interface ServiceFactory {
Service getService();
} class Implementation1 implements Service{ @Override
public void method1() {
System.out.println("Implementation1 method1");
} @Override
public void method2() {
System.out.println("Implementation1 method1");
} } class Implementation2 implements Service{ @Override
public void method1() {
System.out.println("Implementation2 method1");
} @Override
public void method2() {
System.out.println("Implementation2 method1");
} } class ImplementationFactory1 implements ServiceFactory{
@Override
public Service getService() {
// TODO Auto-generated method stub
return new Implementation1();
}
} class ImplementationFactory2 implements ServiceFactory{
@Override
public Service getService() {
// TODO Auto-generated method stub
return new Implementation2();
}
} public class Factories {
public static void serviceSustomer(ServiceFactory factory){
factory.getService().method1();
factory.getService().method2();
}
public static void main(String[] args) {
serviceSustomer(new ImplementationFactory1());
serviceSustomer(new ImplementationFactory2());
} }

  我们还可以将这种方式以内部类的方式来实现

package net.mindview.innerclasses.factory.methodFactoryInnerClass;
/**
* 服务类
*/
interface Service{
void method1();
void method2();
} /**
* 工厂类
*/
interface ServiceFactory {
Service getService();
} /**
* 每一种服务,提供一种工厂. 这种工厂专门创建这种服务.
*/
class Implementation1 implements Service{
private Implementation1(){}
@Override
public void method1() {
System.out.println("Implementation1 method1");
} @Override
public void method2() {
System.out.println("Implementation1 method1");
} //让工厂在内部实现
public static ServiceFactory factory = new ServiceFactory(){
@Override
public Service getService() {
return new Implementation1();
} }; } class Implementation2 implements Service{ @Override
public void method1() {
System.out.println("Implementation2 method1");
} @Override
public void method2() {
System.out.println("Implementation2 method1");
} //让工厂在内部实现
public static ServiceFactory factory = new ServiceFactory(){
@Override
public Service getService() {
return new Implementation2();
} }; } public class Factories {
public static void serviceSustomer(ServiceFactory factory){
factory.getService().method1();
factory.getService().method2();
}
public static void main(String[] args) {
serviceSustomer(Implementation1.factory);
serviceSustomer(Implementation2.factory);
}
}

  我的理解是: 第一种工厂的含义是: 我现在需要一种服务, 然后我找到对应的工厂, 为我提供服务. 工厂再去找对应这种服务的实体.

  而第二种方式呢, 我现在需要服务. 直接就去找这种服务对应的工厂就可以了. 也就是工厂内置了. 就像大公司下有多个子公司, 每个子公司都有自己的工厂.我要那种类型的东西,他就自己给生产了

8. 嵌套类

  如果内部类对象预期外围类对象之间不需要有联系, 那么可以将内部类声明为static的。这种累通常称为嵌套类。要想理解static定义的内部类的含义,就必须记住,普通的内部类对象隐式地保存了一个引用,指向创建他的外围类对象。然而,当内部类是static的时候, 就不是这样了。嵌套类意味着:

  1. 要创建嵌套类的对象, 并不需要外围类的对象。
  2. 不能从嵌套类的对象中访问非静态的对象
  3. 普通的内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类可以有这些东西
    package net.mindview.innerclasses;
    
    public class Parcel11 {
    //ParcelContent被定义为static的,所以是一个嵌套类
    private static class ParcelContent implements Contents {
    int i = ;
    @Override
    public int value() {
    return i;
    }
    } //ParcelDestination 是一个嵌套类. 被定义为static的.所以,它内部可以的有static的成员和方法
    private static class ParcelDestination implements Destination {
    private String label;
    private ParcelDestination(String label){
    this.label = label;
    }
    @Override
    public String readLabel() {
    return label;
    } public static void f(){
    System.out.println(AnotherLabel.x);
    //b()方法是访问不到的
    //AnotherLabel.b();
    }
    static int x = ;
    //他是嵌套在嵌套类内部的嵌套类.
    static class AnotherLabel{
    //内部定义了两个和外部一样的成员方法, 竟然不冲突
    public static void f(){
    System.out.println("这时静态类的静态方法");
    }
    static int x = ;
    //嵌套类中的非静态方法不能被外部访问到. 所以这个方法没有任何意义
    public void b(){
    System.out.println("这时静态类中的静态方法b()");
    }
    }
    } public static Contents getContents(){
    return new ParcelContent();
    } public static Destination getDestination(String s){
    return new ParcelDestination(s);
    } public static void main(String[] args) {
    System.out.println(getContents().value());
    System.out.println(getDestination("北京").readLabel()); //嵌套类中,不能访问非静态方法
    //ParcelDestination.readLabel();
    //但是可以方法静态方法
    ParcelDestination.f(); //嵌套类的使用方式是,类似于静态方法. 将其作为静态方法来使用.
    ParcelDestination.AnotherLabel.x=;
    System.out.println(ParcelDestination.AnotherLabel.x); ParcelDestination.AnotherLabel.f();
    //下面这样写是不对的
    //ParcelDestination.AnotherLabel.b();
    } }

    观看上面说的文字,会有些难以理解,所以, 将这段代码敲一遍,就理解什么意思了。动手很重要啊

9. 接口内部的类

  • 首先,接口里不能放置任何代码, 但是嵌套类可以.
  • 你放到接口中的任何类都自动式public static的.
  • 你可以在内部类中实现外围类的接口. 示例如下:
    package net.mindview.innerclasses;
    /**
    * 定义在接口内部的类
    */
    public interface ClassInInterface {
    void howdy();
    //这里static必须是显示标记出来的,否则这个类将不能运行
    static class Test implements ClassInInterface { @Override
    public void howdy() {
    System.out.println("Howdy!");
    } public static void main(String[] args) {
    Test t = new Test();
    t.howdy();
    }
    }
    }

    注意, 如果想运行main方法, 这里的嵌套类必须是static的.

  • 如果想创建某些公共代码, 使得他们可以被某个接口的所有实现类所共用, 那么使用接口内部的嵌套类会显得很方便.
  • 例如: 我们可以在每个类中写一个mian方法用来测试这个类, 这样做有一个缺点, 那就是要写好多遍,而且, 必须通过编译器的编译, 我们可以使用嵌套类改善
    package net.mindview.innerclasses;
    
    public class TestBed {
    public void f(){
    System.out.println("f()");
    } static class Testers{
    public static void main(String[] args) {
    TestBed t = new TestBedTest();
    t.f();
    }
    }
    }

    再说的白话一点,就是在接口中定义一个这样的嵌套类. 然后定义mian方法, 在main方法中使用嵌套类. 当有一个新的对象继承了这个类的时候, 就在这个类中的main方法进行测试就好了. 这样的好处是, 当我打包发布到正式环境的时候, 我想删除所有的main方法,因为他们的存在也会被编译器编译, 降低效率. 如果只有一个接口的嵌套类中定义的main方法,那么删起来就方便很多了。不明白的话,在看下面这个例子,就懂了

    package net.mindview.innerclasses;
    /**
    * 定义在接口内部的类
    */
    public interface ClassInInterface {
    void howdy();
    //这里static必须是显示标记出来的,否则这个类将不能运行
    static class Test implements ClassInInterface { @Override
    public void howdy() {
    System.out.println("Howdy!");
    } public static void main(String[] args) {
    //测试第一个实现了接口的类
    ClassInInterface t = new Test();
    t.howdy();
    //测试第二个实现了接口的类
    ClassInInterface t1 = new ClassInInterfaceTest();
    t1.howdy();
    }
    }
    }
    package net.mindview.innerclasses;
    
    public class ClassInInterfaceTest implements ClassInInterface{
    
        @Override
    public void howdy() {
    System.out.println("hhhh");
    }
    }
  • 接口中嵌套类如何创建实例化对象。 参考习题20
    package net.mindview.innerclasses.test20;
    interface InnerInInterface{
    static class Inner{
    public Inner(){
    System.out.println("嵌套类构造方法");
    }
    }
    } public class Test20 {
    public static void main(String[] args) {
    //直接使用 new 外围类.嵌套类
    InnerInInterface.Inner inner = new InnerInInterface.Inner();
    }
    }

10. 从多层嵌套类中访问外部类的成员

  注意下面这个例子是如何创建内部类的。

package net.mindview.innerclasses;
/**
* 多层嵌套类访问外部成员
*/ class A{
private void f(){};
class B{
private void b(){};
class C {
void c(){
f();
b();
};
}
}
}
public class MutliNestingAccess { public static void main(String[] args) {
A a = new A();
A.B b = a.new B();
A.B.C c = b.new C();
c.c();
} }

iooo

java编程思想第四版第十章总结的更多相关文章

  1. java编程思想第四版第十章习题

    第一题 package net.mindview.innerclasses; public class Outer { class Inner { Inner(){ System.out.printl ...

  2. java编程思想第四版中net.mindview.util包下载,及源码简单导入使用

    在java编程思想第四版中需要使用net.mindview.util包,大家可以直接到http://www.mindviewinc.com/TIJ4/CodeInstructions.html 去下载 ...

  3. 《Java编程思想第四版》附录 B 对比 C++和 Java

    <Java编程思想第四版完整中文高清版.pdf>-笔记 附录 B 对比 C++和 Java “作为一名 C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且 Java 的语法无疑是 ...

  4. Java编程思想第四版勘误

    坊间传说这本书翻译得很烂,我倒觉得还好.虽然看原文更准确,但是如果在具备一定编程思维和基础.能够看出来疑问的情况下,还是看中文更快一些,而且这本书本身也不适合初学者看.当然,错误和不通顺还是有的,而且 ...

  5. Java编程思想第四版完整中文高清版.pdf

    Java编程思想第四版完整中文高清版.pdf 链接: https://pan.baidu.com/s/1vV5BHF3L-bnaG6WGurdJ_A 提取码: vigy 复制这段内容后打开百度网盘手机 ...

  6. 《Java编程思想第四版完整中文高清版.pdf》-笔记

    D.2.1 安插自己的测试代码 插入下述“显式”计时代码,对程序进行评测: long start = System.currentTimeMillis(); // 要计时的运算代码放在这儿 long ...

  7. 《Java编程思想第四版》附录 C Java 编程规则

    附录 C Java 编程规则 本附录包含了大量有用的建议,帮助大家进行低级程序设计,并提供了代码编写的一般性指导: (1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符 ...

  8. java编程思想第四版第九章总结

    1. 策略设计模式 参考这篇文章:http://blog.csdn.net/chenjie19891104/article/details/6396458 讲的很清楚,策略设计模式.并且举了一个例子, ...

  9. java编程思想第四版第十一章习题

    第一题 package net.mindview.holding.test1; import java.util.ArrayList; import java.util.List; /** * 沙鼠 ...

随机推荐

  1. Flink Connector 深度解析

    作者介绍:董亭亭,快手大数据架构实时计算引擎团队负责人.目前负责 Flink 引擎在快手内的研发.应用以及周边子系统建设.2013 年毕业于大连理工大学,曾就职于奇虎 360.58 集团.主要研究领域 ...

  2. eclipse提交代码到GitHub

    1.配置git 2.右键项目--> Team--> Share Project... 3.右键项目--> Team--> Commit...

  3. 8.Linux用户管理(上)

    1.什么是用户? 能正常登陆系统的都算用户 windows系统和linux系统的用户有什么区别? 本质上没有区别, linux支持多个用户同一时刻登陆系统, 互相之间不影响 而windows只允许同一 ...

  4. ESP8266开发之旅 进阶篇⑥ ESP-specific APIs说明

    1.前言     在介绍Arduino Core For ESP8266的时候,博主着重讲解了WIFI库的使用,但是并没有涉及到ESP8266硬件本身的一些特有API.所以,这一章我们将讲解ESP82 ...

  5. 百万年薪python之路 -- MySQL数据库之 Navicat工具和pymysql模块

    一. IDE工具介绍(Navicat) 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具,我们使用Navicat工具,这个工具本质上就是一个socket客户端,可视化的连接 ...

  6. 【网络安全】Dos攻击科普文

    目录 DOS攻击 什么是DOS攻击 攻击手段分类 具体的攻击方式举例 优秀博客参考 DDOS攻击 DOS攻击 什么是DOS攻击 DOS是Denial of Service的简称,用中文简单翻译就是拒绝 ...

  7. Python网络爬虫之cookie处理、验证码识别、代理ip、基于线程池的数据爬去

    本文概要 session处理cookie proxies参数设置请求代理ip 基于线程池的数据爬取 引入 有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时, ...

  8. 在线预览office文件

    Office Online 实现在线预览 office的在线预览,针对不同的浏览器版本和系统具有要求,具体的相关文档请参考官方文档. 利用office online 平台进行office 文档的在线查 ...

  9. Everything可能泄漏大量电脑敏感资料

    一款好用的文件搜索工具Everything被批露出现重大问题: Everything可以打开http服务,在没有加密的情况下任何外网电脑都可以连接的. 因此,Everything可能泄漏大量电脑敏感资 ...

  10. Web for pentester_writeup之LDAP attacks篇

    Web for pentester_writeup之LDAP attacks篇 LDAP attacks(LDAP 攻击) LDAP是轻量目录访问协议,英文全称是Lightweight Directo ...