Java编程思想(七) —— 内部类

刚刚看到论坛推荐,阿里的校招没想到8月底就开始了,等春招再去试试,现在还是太嫩了点。

将一个类的定义放到另一个类定义的内部——内部类。用java写Android的朋友经常用的Listener的东西,里面就是内部类。而且,不要单纯地以为就java才能开发Android。

1)简单的内部类

内部类的功能看似隐藏了代码,其实不然。

public class Ticket {
    class Destination{
        private String content;
        Destination(String s){
            content = s;
        }
        String showContent(){
            return content;
        }
    }

    public void show(String dest){
        Destination d = new Destination(dest);
        System.out.println(d.showContent());
    }
    public static void main(String[] args) {
        Ticket t = new Ticket();
        t.show("BeiJing");
    }
}

一个简单的内部类,就是一个普通类嵌套在内部。

    public Destination getDestination(){
        return new Destination("ShangHai");
    }
    public static void main(String[] args) {
        Ticket t = new Ticket();
        Ticket.Destination dest = t.getDestination();
        Destination d = t.new Destination("GuangZhou");
        t.show("BeiJing");
    }

如果从静态方法中创建内部类对象,如果是直接new的话要用上面的写法,而用了返回值为对象的方法的需要指明对象的类型。

2)链接到外部类

内部类拥有其外围类(enclosing class,enclosing是封闭的意思,书上翻译成外围类对象)的所有元素的访问权。直接用书上的例子。

public class Sequence {
    private Object[] item;
    private int next = 0;
    public Sequence(int size){
        item = new Object[size];
    }
    public void add(Object x){
        if(next<item.length){
            item[next++]=x;
        }
    }

    private class SimpleItertor implements MyIterator{
        private int index = 0;
        /*public boolean end() {
            if(next == item.length){
                return true ;
            }
            return false;
        }代码冗余 其实可以写的更简洁
        */

        public boolean end() {
            return index == item.length;
        }
        public Object current() {
            return item[index];
        }

        public void next() {
            if(index<item.length){
                index ++;
            }
        }
    }

    public MyIterator iterator(){
        return new SimpleItertor();
    }

    public static void main(String[] args) {
        Sequence s = new Sequence(10);
        for(int i = 0; i < 10 ; i++){
            s.add(i);
        }
        MyIterator i = s.iterator();
        while(!i.end()){
            System.out.println(i.current());
            i.next();
        }
    }
}

为什么把这个例子写进来呢,一个是这个类似我们经常使用容器的Iterator,其实也应用了设计模式——迭代器模式。还有内部类中用了外围类的私有成员进行操作。

3)使用.this和.new

public class Outer {
    class Inner{
        Outer getOuter(){
            return Outer.this;
        }
    }
}

如果是单纯的this的话,this指向的是Outer.Inner,如果返回Outer对象,还是需要Outer.this。

.new的话在第一个知识点的时候提到了。需要

 Destination d = t.new Destination("GuangZhou");

内部类对象会偷偷地连接到外部类对象,所以在创建外部类对象之前是不能创建内部类的,当时如果为静态内部类(嵌套类)就不需要外部类对象的引用。

public class Outer {
     static class Inner{
    }
     public static void main(String[] args) {
        Inner i = new Inner();
    }
}

4)内部类用处——向上转型

更高深的隐藏代码。其实书上再举例子。不过回头再看发现已经用过一次了。

private class SimpleItertor implements MyIterator{}
public MyIterator iterator(){ return new SimpleItertor(); }

其实我们在代码已经隐藏了这个实现类的实现细节,属性为私有,返回的时候是将SimpleIterator向上转型为通用的接口。

5)方法和作用域中的内部类。

public class Outer {
    public void get(){
        class Inner{
        }
    }
}

方法内部,称为局部内部类。

作用域方面,如果内部类声明在if条件语句下作用域中,那超出这个域也是不可用的。

6)匿名内部类

public class Outer {
    public Sequence get() {
        return new Sequence(1) {};
      }
}

虽然返回Sequence对象,但是却是你可以在花括号里面定义自己的东西。这对于外面来说就是匿名的。

如果匿名内部类使用其外部定义对象,参数要有final。

class Inner{}

public class Outer {
    public Inner get(final String s){
        return new Inner(){
           String type = s;
        };
    }
}

Cannot refer to a non-final variable s inside an inner class defined in a different method.不能把内部类里面非final变量s放进一个不同的方法中定义。

7)嵌套类

上面提到的静态内部类。和静态方法的特点类似。创建嵌套类对象不需要外部类对象引用,不能从嵌套类对象访问非静态外围类对象(静态方法的是不能在静态方法中使用非静态方法)。

8)为什么需要内部类

这东西设计来干啥,要知道其实语言是人设计的,特性也是自己设计的,没用的是不会专门设计出来的。

内部类实现接口和外围类实现接口是不同的,每个内部类都能继承接口,外围类继承了谁并不会对内部类造成影响。在使用GUI的时候,更能感受到内部类的价值。

9)闭包和回调

闭包,closure,指的是可调用对象记录一些信息,信息来自创建他的作用域。其实内部类就是。

10)内部类标识符

在没有使用IDE之前的那段时间,纯粹在dos窗口编译的时候,经常会去看编译后的文件是什么样子的。有时会看到Outer$Inner.class文件的存在,其实这就是编译器编译的结果,外围类加上$再加上内部类的名字。

接口和内部类这两章真的很复杂很深奥,内部类这里还有一个控制框架是我没写出来的。C++没有这些东西,接口和内部类的结合可以解决C++多重继承的问题。写的还不多,接触到这两者还比较少,以后接触到再来看就知道价值所在了。

时间: 2024-10-12 07:11:41

Java编程思想(七) —— 内部类的相关文章

Java编程思想:内部类基础部分

public class Test { public static void main(String[] args) { // Parcel1.test(); // Parcel2.test(); // Sequence.test(); DotThis.test(); } } class Parcel1 { class Contents { private int i = 11; public int value() { return i; } } class Destination { pri

【Java编程思想】10.内部类

将一个类的定义放在另一个类的定义内部,这就是内部类. 10.1 创建内部类 内部类的名字是嵌套在外部类里面的 外部类可以有方法,返回一个指向内部类的调用.(外部类中可以调用内部类) 如果在外部类中,希望能在除了静态方法之外的任意位置创建某个内部类对象,那么可以向下面这样指明对象类型. OuterClassName.InnerClassName x = new InnerClassName(); 10.2 链接到外部类 在创建了一个内部类的对象后,内部类与制造它的外围对象(enclosing ob

《On Java 8》中文版,又名《Java 编程思想》中文第五版

来源:LingCoder/OnJava8 主译: LingCoder 参译: LortSir 校对:nickChenyx E-mail: [email protected] 本书原作者为 [美] Bruce Eckel,即(Thinking in Java 4th Edition,2006)的作者. 本书是事实上的 Thinking in Java 5th Edition(On Java 8,2017). Thinking in Java 4th Edition 基于 JAVA 5 版本:On

《Java编程思想(第4版)》pdf

下载地址:网盘下载 内容简介 编辑 本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形.从Java的基础语法到最高级特性(深入的面向对象概念.多线程.自动项目构建.单元测试和调试等),本书都能逐步指导你轻松掌握.[1] 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作.本书的作者拥有多年教学经验,对C.C++以及Java语言都有独到.深入的见解,以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概

java编程思想第1、2、3章细节总结

转眼已经大二学期的暑假,已经使用java有一年了,才开始看thinking in java 这本经典书籍,算是做个系统总结吧,只列一些目前还掌握不熟的需要谨记的知识点. 第一章:对象导论 1.java中的权限:public,protected,private,default. public:可以被任何对象访问. protected:只能在本类和本类的内部类中使用,通过继承操作可以继承下去. private:只能在本类和本类的内部类中使用. default:如果没有加任何权限,则默认就是这个def

Java编程思想重点笔记(Java开发必看)

Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面 试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理解题(比如is-a关系和has-a关系的区别),也有深入的涉及RTTI和JVM底层 反编译知识. 1. Java中的多态性理解(注意与C++区分) Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意

Java编程思想读书笔记之内部类

现在是够懒得了,放假的时候就想把这篇笔记写出来,一直拖到现在,最近在读<Java编程思想>,我想会做不止这一篇笔记,因为之前面试的时候总会问道一些内部类的问题,那这本书的笔记就从内部类开始说起. 一.为什么需要内部类 1.一个内部类的对象可以访问它的外围类的私有数据. 2.对于同一个包中的其他类来说,内部类能够隐藏起来. 3.使用内部类实现多重继承. 二.内部类重要提要 1.在方法内部或者方法内部的作用域的内部类 eg:方法内部的内部类 public interface InnerInterf

java编程思想-基础

interface: 方法默认为public:成员变量默认 static and final 对象数组的定义:理解? 多接口继承:可以多个接口,但只有一个具体类,具体类在前面 自:多接口继承时,来自不同接口的同名方法怎么处理呢? java重载不能依靠返回类型加以区分(C++可以),也不能依靠checked 异常类型区分 变量定义中的系列定义(逗号隔开):变量名 = 值,其它公共 自:类中,自己引用自己的理解(如,链表节点元素).静态看成动态,编译器的本质实现 内部类和普通类区别:内部类可priv

70.JAVA编程思想——Web应用

70.JAVA编程思想--Web应用 创建一个应用,令其在真实的Web 环境中运行,它将把Java 的优势表现得淋漓尽致.这个应用的一部分是在Web 服务器上运行的一个Java 程序,另一部分则是一个"程序片"或"小应用程序"(Applet),从服务器下载至浏览器(即"客户").这个程序片从用户那里收集信息,并将其传回Web 服务器上运行的应用程序.程序的任务非常简单:程序片会询问用户的E-mail 地址,并在验证这个地址合格后(没有包含空格,而