Java编程思想第四版第十章学习——内部类(1)

原创 2016年05月30日 23:45:45

内部类是指在一个外部类的内部再定义一个类。类名不需要和文件名相同。

1、成员内部类

成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
注意:成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。

2、成员内部类的引用和创建

在内部类要生成对外部类对象的引用,可以使用外部类的名字后紧跟”.this”。而想直接创建内部类的对象,必须使用外部类的对象来创建该内部类对象,可以使用外部类的变量名后紧跟“.new”。注意,在外部类对象之前不能创建内部类对象,除非创建的是嵌套类(静态内部类)。

3、局部内部类——在方法和作用域中定义内部类

可以在一个方法里面或者在任意的作用域内定义内部类。这么做有两个好处:
(1)可以实现某个接口,从而可以创建并返回对其的引用
(2)创建一个类来辅助解决复杂问题,并且这个类是不可用的。

//定义在方法之内的内部类——Java编程思想例子
public class Parcel4 { 
    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) { 
        Parcel4 p = new Parcel4(); 
        Destination d = p.destination("Tasmania"); 
    } 
} 
//定义在if作用域的内部类——Java编程思想例子
public class Parcel5 { 
    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(); 
        } 
    } 

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

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

局部内部类也像别的类一样进行编译,但只是作用域不同而已,只在该方法或条件的作用域内才能使用,退出这些作用域后无法引用的。

4、匿名内部类

匿名内部类创建格式如下:

new 父类构造器(参数列表)|实现接口()    
    {    
     //匿名内部类的类体部分    
    } 

从格式上可以发现,使用匿名构造类必须要继承一个父类或者实现一个接口,且不能同时发生。匿名构造类没有class关键字,直接使用new来生成一个对象的引用(隐式)。例子如下:

interface Hello{
     void say();
}

public class Dada{
    public static void main(String[] args){
        Hello h = new Hello(){
            public void say(){
             System.out.println("C++");
            }
        };
        h.say();
    }
}/*Output
C++
*///
abstract class Hello{
    public abstract void say();
}

public class Dada{
    public static void main(String[] args){
        Hello h = new Hello(){
            public void say(){
             System.out.println("C++");
            }
        };
        h.say();
    }
}/*Output
C++
*///

注意
在使用匿名内部类的过程中,我们需要注意如下几点:
1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
2、匿名内部类中是不能定义构造函数的。
3、匿名内部类中不能存在任何的静态成员变量和静态方法。
4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6、匿名内部类仅能使用一次,创建匿名内部类时它会立即创建一个该类的实例,该类的定义会立即消失,所以匿名内部类是不能够被重复使用。

方法的形参需要设置为final
给匿名内部类传递参数的时候,若该形参在内部类中需要被使用,那么该形参必须要为final。也就是说:当所在的方法的形参需要被内部类里面使用时,该形参必须为final。例如

public class OuterClass {  
    public void display(final String name,String age){  
        class InnerClass{  
            void display(){  
                System.out.println(name);  
            }  
        }  
    }  
}  

内部类并不是直接调用方法传递的参数,而是利用自身的构造器对传入的参数进行备份,自己内部方法调用的实际上是自己的属性而不是外部方法传递进来的参数。
但是为什么要加final呢?因为为了保持内部类和外部类的形参的一致性。通过拷贝引用,内部类为了避免引用值发生改变,如外部类的方法修改而导致内部类得到的值不一致。于是就用final让引用不可改变。

匿名内部类的初始化
匿名内部类中没有构造器,一般通过代码块来完成初始化工作。

public class Parcel10{
    public Destination
    destination (final String dest,final float price){
        return new Destination(){
            private int cost;
            {
                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!
*///

5、嵌套类

如果不需要内部类与其外围类对象之间的联系,可以将内部类声明为static,通常称为嵌套类。
嵌套类与普通内部类的区别:
普通内部类对象隐式地保存了一个引用,指向创建它的外围类对象,而要创建嵌套类对象,不需要其外围类的对象,也不能从嵌套类的对象中访问非静态的外围类对象。

接口内部的类
正常情况下,不能在接口内部放置任何代码。但嵌套类可以作为接口的一部分,放到接口中的任何类都自动地是public和static。
甚至可以在内部类中实现外围接口,如下所示

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()方法来测试这个类,那就必须带着那些已经编译过的额外代码,这带来额外的开销。此时可以用嵌套类来放置测试代码。

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()
*///

在编译后,上述代码会生成一个独立的测试类TestBedTester(Unix/Linux)。可以用这个类来测试,但是不必在发布的产品中包含它,在将产品打包前删去这个测试类。

从多层嵌套类中访问外部类的成员
一个内部类即使被嵌套多层,它也能透明地访问所有它所嵌入的外围类的所有成员。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java编程思想第四版读书笔记——第十章 内部类

Java编程思想第四版读书笔记——第十章 内部类
  • severusyue
  • severusyue
  • 2015年10月27日 10:11
  • 399

《Java编程思想》学习笔记:内部类

我们可以在一个类的创建多个内部类,相当于带了很多小弟,这些小弟总得认识自己的老大是谁吧(指向外围类对象的引用),这些小弟可以共享我的资源,同时,这些小弟都很优秀,能够独立完成我交给他们的某些工作(一个...
  • JF_1994
  • JF_1994
  • 2017年02月08日 21:08
  • 362

《Java编程思想第四版》笔记---21章(1) 并发

线程是进程中一个任务控制流序列,由于进程的创建和销毁需要销毁大量的资源,而多个线程之间可以共享进程数据,因此多线程是并发编程的基础。 多核心CPU可以真正实现多个任务并行执行,单核心CPU程序其实不是...
  • u012861467
  • u012861467
  • 2016年08月27日 00:19
  • 700

Java编程思想第四版第十章学习——内部类(2)

1、使用内部类的意义内部类可以继承多个具体的或抽象的类,内部类使得多重继承变得完善。每个内部类都能独立地继承一个类或接口的实现,所以无论外围是否已经继承了某个类或接口的实现,对于内部类都没有影响。 ...
  • Muc_hui
  • Muc_hui
  • 2016年06月03日 14:52
  • 413

《Java编程思想》第四版之内部类学习——神奇而又实用

版权声明:学习内容均为本人笔记,代码均为本人依据课本所写或改编 引言:内部类,即将一个类的定义放在另一个类的定义内部。内部类与组合是完全不同的概念。内部类看似是一种代码的隐藏机制,其实,它能够了解外...
  • Audience_
  • Audience_
  • 2017年06月13日 01:13
  • 309

《Java编程思想》之内部类——深奥而复杂

1、当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地(从实现某个接口的对象,得到对此接口的引用,与向上转型为这个对象的基类,实质上效果是一样得。)这是因为此内部类——某个接...
  • Cannel_2020
  • Cannel_2020
  • 2012年01月29日 19:23
  • 2485

JAVA编程思想第4版读书笔记

原来download了网上一个第1版的Java编程思想,里面讲的还是Java1.0和Java1.1时代的故事。我看到一半,又找到第三版,发现讲的是Java 1.4时代的故事。到第4版,讲Java 1....
  • androidTang
  • androidTang
  • 2015年10月01日 11:30
  • 788

Java编程思想(第四版)第一章内容要点总结

许多我们看过的编程书都会忘记,所以我选择可以笔记的形式将其中的要点摘录下来,初次做笔记,希望与大家共勉...
  • qq_31965147
  • qq_31965147
  • 2016年03月15日 21:54
  • 575

Java编程思想第四版读书笔记——第八章 多态

本来不打算看了,现在面试笔试发现还是要重新拾起来看一遍。老老实实啃砖吧  第八章 多态 在面向底下的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征。 “封装”通过合并特征和行为来创建新...
  • severusyue
  • severusyue
  • 2016年06月20日 22:23
  • 709

[PDF]Java编程思想第四版完整中文高清版(亲测真实)

学习java,经人推荐购买了java编程思想第四版,后发现看书时间不长,主要因为书本拿着不方便,后上网查找java编程思想4 PDF版,可是很多是一版和二版的PDF,因为要和书本一致,故找了很多,终于...
  • qq_26949717
  • qq_26949717
  • 2017年08月24日 14:28
  • 2196
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java编程思想第四版第十章学习——内部类(1)
举报原因:
原因补充:

(最多只允许输入30个字)