- 浏览: 122591 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (130)
- JUnit4学习 (0)
- Spring3.X学习 (2)
- 日记 (1)
- 文学类 (2)
- Java (15)
- Thingking In Java (11)
- org.apache.poi (4)
- XML (2)
- Log4j (1)
- Jar包收集 (2)
- ExtJs (1)
- 汇编语言 (11)
- 开发工具 (0)
- 电子书 (2)
- Oracle (6)
- Ajax (1)
- Jquery (2)
- myBatis (1)
- Spring2.5学习 (6)
- Tomcat (1)
- MyEclipse (1)
- JSP (1)
- Linux shell 脚本攻略 (7)
- Python3 (2)
- HTML5 (5)
- JavaScript (7)
- Hadoop-1.2.1 (2)
- Python2.7 (12)
- Django (3)
- 软件安装 (1)
- 高级Bash脚本编程指南 (7)
- Linux命令 (3)
- Ansible (2)
- MySQL (2)
- 病历 (1)
- 操作系统 (1)
- CSS (0)
- CSS3 (0)
- 面试题 (1)
最新评论
-
hw1287789687:
http://www.cnblogs.com/hccwu/p/ ...
Java获取真实的IP地址 -
liubey:
String ip = request.getHeader(& ...
Java获取真实的IP地址 -
bewithme:
我记得uploadify这破东西只能在chrome浏览器中才有 ...
Struts2结合Jquery.uploadify上传插件的应用 -
MrLee23:
http://mrlee23.iteye.com/admin/ ...
Struts2结合Jquery.uploadify上传插件的应用 -
crysik:
import com.eshore.ppm.model.com ...
Struts2结合Jquery.uploadify上传插件的应用
2013年6月23日 星期日 16时50分56秒
第十章 内部类
可以将一个类的定义放在另一个类的定义内部,这就是内部类。
内部类允许你把一些逻辑相关的类组织在一起,并控制位于内部类的可见性。 内部类与组合不同。
10.1 创建内部类
创建内部类的方式就如你想的一样----把类的定义置于外围类的里面。
package chapter10;
/*@name RandomDoubles.java
* @describe 10.1 创建内部类
* @since 2013-06-23 16:59
* @author 张彪
*/
public class Parcel1 {
class Contents{
private int i=11;
public int value(){return i;}
}
class Desination{
private String label;
Desination(String label){this.label=label;}
String readLabel(){return label;}
}
public void ship(String dest){
Contents c=new Contents();
Desination d=new Desination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Parcel1 p=new Parcel1();
p.ship("Tasmania");
}
}
//当我们在ship()方法里面使用内部类的时候,与使用不同类没什么区别。在这里,实际的区别只是内部类的名字嵌套在Parel1里面的。更典型的情况是,外部类将有一个方法,方法返回一个指向内部类的引用,就像在to和contents()方法中看到的那样。
package chapter10;
/*@name RandomDoubles.java
* @describe 10.1 创建内部类
* @since 2013-06-23 16:59
* @author 张彪
*/
public class Parcel2 {
class Contents{
private int i=11;
public int value(){return i;}
}
class Desination{
private String label;
Desination(String label){
this.label=label;
}
String readLabel(){
return label;
}
}
public Desination to(String s){
return new Desination(s);
}
public Contents contents(){
return new Contents();
}
public void ship(String dest){
Contents c=new Contents();
Desination d=new Desination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Parcel2 p=new Parcel2();
p.ship("Tasmania");
Parcel2.Contents c=p.contents();
Parcel2.Desination d= p.to("Boring");
}
}
//如果想在外部类的非静态方法中之外的任何位置创建某个内部类的对象。那么必须在main()方法中那样,具体地指明这个对象的类型。OuterClassName.InnerClassName.
10.2 链接到外部类
到目前为止,内部类似乎还只是一种名字隐藏和组织代码的模式。这些是很有用,但还不是最引人注目的。当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联 系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其他外围类的所有元素的访问权限。(这与C++嵌套类的设计非常不同,在C++中只是单纯的名字隐藏 机制,与外围对象没有联系)
package chapter10;
/*@name Sequence.java
* @describe 10.2 链接到外部类
* @since 2013-06-23 17:48
* @author 张彪
*/
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 s=new Sequence(10);
for(int i=0;i<10;i++){
s.add(Integer.toString(i));
}
Selector selector=s.selector();
while(!selector.end()){
System.out.println(selector.current());
selector.next();
}
}
}
注意:内部类自动拥有对外围类所有成员的访问权限。这是如何做到的呢?当某个外围类的对象创建了一个内部类对象是,此内部类对象必定会秘密地捕获一个指向那个外围类的引用。
10.3 使用.this和.new
10.3.1 .this的用法
如果你需要生成对外边对象的引用,可以使用外边类的名字后面紧跟圆点和this。这样产生的引用自动地具有正确的类型。
package chapter10;
/*@name DotThis.java
* @describe 10.3 使用.this和.new
* @since 2013-06-23 17:48
* @author 张彪
*/
public class DotThis {
void f(){System.out.println("DotThis.f()");}
public class Inner{
public DotThis outer(){
return DotThis.this; //注意:this的使用
}
}
public Inner inner(){
return new Inner();
}
public static void main(String[] args){
DotThis d=new DotThis();
DotThis.Inner n= d.inner();
n.outer().f();
}
}
10.3.2 .new的用法
有时你可能要告知某些其他对象,去创建其某个内部类的对象。要实现此目的,你必须在new表达式中提供对其他外部对象的引用,这是需要使用.new语法。例如:
package chapter10;
/*@name DotNew.java
* @describe 10.3 使用.this和.new
* @since 2013-06-23 18:48
* @author 张彪
*/
public class DotNew {
public class Inner{}
public static void main(String[] args){
DotNew dn=new DotNew();
DotNew.Inner n=dn.new Inner(); //注意.new的用法
//dn.new DotNew.Inner(); 不能这样声明
//Inner r=new Inner(); 也不能这样声明
}
}
要想直接创建内部类的对象,必须使用外部类的对象来创建内部类对象。这样解决了内部类名字作用域的问题。因此你不必声明(实际上你不能声明)dn.new DotNew.Inner()
10.3.4 嵌套类(静态内部类)
在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地链接到创建它的外部类对象上。但是如果你创建的是嵌套类(静态内部类),那么它就不需 要对外部类对象的引用。
package chapter10;
/*@name DotNew.java
* @describe 10.3 嵌套类(静态内部类)
* @since 2013-06-23 19:11
* @author 张彪
*/
public class Pracel3 {
class Contents{
private int i=11;
public int value(){return i;}
}
class Destination{
private String label;
Destination(String whereTo){this.label=whereTo;}
String readLabel(){return label;}
}
public static void main(String[] args){
//Must use instance of outer class to create an instance of the inner class
Pracel3.Contents c=(new Pracel3()).new Contents();
Pracel3.Destination d=(new Pracel3()).new Destination("Tasmania");
}
}
10.4 内部类和向上转型
当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地。(从实现了某个接口的对象,得到对此接口的引用,与向上转型为这个对象的基类,实质上效 果是一样的。)这是因为此内部类--某个接口的实现--能够完全不可见,并且不可用。所得到的只是指向基类或接口的引用,所以能够很方便地隐藏实现的细节。
我们可以创建前一个示例的接口:
package chapter10;
import chapter10.Contents;
import chapter10.Destination;
public class Pracel4 {
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 label){this.label=label;}
public String readLabel(){return label;}
}
public Destination destination(String s){
return new PDestination(s);
}
public Contents contents(){
return new PContents();
}
public static void main(String[] args){
Pracel4 p=new Pracel4();
Destination pd= p.destination("Tasmania");
Contents c=p.contents();
Pracel4.PContents pc= p.new PContents(); //在同一个类就可以这样访问;若在不同类中,则不能访问私有类。
}
}
10.5 在方法和作用域内的内部类
到目前为止,所见的都是“平凡的”内部类,简单而且容易理解。然而,内部类的语法覆盖了大量的其他的更加难以理解的技术。例如。可以在一个方法里面或者在任意作用域内定义 内部类。这么做有两个理由:
1)如前所示,你实现了某类型的接口,于是可以创建并返回对其引用。
2)你要解决一个复杂的问题,想创建一个类用来辅助你的解决方案,但又不希望这个类是公共可用的。
下面的例子,先前的代码将被修改,以用于实现:
1)一个定义在方法中的类
2)一个定义在作用域中的类,此作用域在方法的内部
3)一个实现了接口的匿名类
4)一个匿名类,它扩展了有非默认构造器的类
5)一个匿名类,它执行字段初始化
6)一个匿名类,它通过实例初始化实现构造(匿名类不可能有构造器)
下面这个例子展示了在方法的作用域内(而不是在其他类的作用域内)创建一个完整的类。这称为局部内部类。
package chapter10;
import chapter10.Pracel4.PDestination;
/*@name DotNew.java
* @describe 10.5 在方法的作用域内(而不是在其他类的作用域内)创建一个完整的类。这称为局部内部类。
* @since 2013-06-23 22:49
* @author 张彪
*/
public class Parcel5 {
public Destination destination(String s){
class PDestination implements Destination{
private String label;
private PDestination(String whereTo){this.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");
System.out.println(d.readLabel());
}
}
10.5.1 在任意的作用域内嵌入一个内部类
package chapter10;
/*@name DotNew.java
* @describe 10.5 如何在任意的作用域内嵌入一个内部类
* @since 2013-06-23 22:49
* @author 张彪
*/
public class Parcel6 {
private void internalTracking(boolean b){
if(b){
class TrackingSlip{
private String id;
TrackingSlip(String id){this.id=id;}
String getSlip(){return id;}
}
TrackingSlip ts=new TrackingSlip("slip");
String s=ts.getSlip();
}
}
public void track(){internalTracking(true);}
public static void main(String[] args){
Parcel6 p=new Parcel6();
p.track();
}
}
TrackingSlip类被嵌入在if语句的作用域内,这并不是说该类的创建是有条件的,它其实与别的类一起编译过了。
10.6 匿名内部类
看下面的这个例子看起来有点奇怪哦:
package chapter10;
/*@name DotNew.java
* @describe 10.7 匿名内部类
* @since 2013-06-24 9:00
* @author 张彪
*/
public class Parcel7 {
public Contents contents(){
return new Contents(){ //insert a class definition
private int i=11;
public int value(){return i;}
};
}
public static void main(String[] args){
Parcel7 p=new Parcel7();
Contents s =p.contents();
System.out.print(s.value());
}
}
contents()方法将返回值的生成与表示这个返回值的类的定义结合在一起!另外这个类是匿名的,它没有名字,更糟的是,看起来似乎是你正要创建一个Contents对象。但是然后你却说:"等一等,我想在这里插入一个类的定义。"
这种奇怪的语法指的是:“创建一个继承自Contents的匿名类的对象。”通过new表达式返回的引用被自动向上转型为对Contents的引用。
上述匿名内部类的语法是下述形式的简化形式:
package chapter10;
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 s =p.contents();
System.out.print(s.value());
}
}
在匿名内部类中定义字段并执行初始化操作:
package chapter10;
/*@name DotNew.java
* @describe 10.6 匿名内部类中定义字段并执行初始化操作
* @since 2013-06-24 9:00
* @author 张彪
*/
public class Parcel9 {
public Destination destination(final String dest){
return new Destination(){
private String label=dest;
public String readLabel(){return dest;}
};
}
public static void main(String[] args){
Parcel9 p=new Parcel9();
Destination d=p.destination("Timanis");
System.out.println(d.readLabel());
}
}
注意:如果定义了一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译会要求其参数引用的是final的。如上例destination()方法,否则编译器会报错。
package chapter10;
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 bugget!");}
}
private String label=dest;
public String readLabel(){return label;}
};
}
public static void main(String[] args){
Parcel10 p=new Parcel10();
Destination d=p.destination("Tamanis", 120);
}
}
匿名内部类与正规的继承相比有些受限,因为匿名内部类既可以扩展类,也可以实现接口,但是不能两者兼备。而且是如果实现了接口,也只能实现一个接口。
10.6.1 再访工厂方法
看看在使用内部类时,Factory实例变得多么美妙呀:
package chapter10;
/*@name DotNew.java
* @describe 10.6.1 再访工厂方法
* @since 2013-06-24 14:52
* @author 张彪
*/
interface Service{
void method1();
void method2();
}
interface ServiceFactory{
Service getService();
}
class Implementation1 implements Service{
private Implementation1(){}
public void method1(){System.out.println("Implementation1.method1()");}
public void method2(){System.out.println("Implementation1.method2()");}
public static ServiceFactory factory=new ServiceFactory(){
public Service getService(){
return new Implementation1();
}
};
}
class Implementation2 implements Service{
private Implementation2(){}
public void method1(){System.out.println("Implementation2.method1()");}
public void method2(){System.out.println("Implementation2.method2()");}
public static ServiceFactory factory=new ServiceFactory(){
public Service getService(){
return new Implementation2();
}
};
}
public class Factories {
public static void serviceConsumer(ServiceFactory factory){
Service s=factory.getService();
s.method1();
s.method2();
}
public static void main(String[] args){
serviceConsumer(Implementation1.factory);
serviceConsumer(Implementation2.factory);
}
}
现在用于Implementation1和Implementation2的构造器都可以是private的,并且没有必要去创建作为工厂的具体名。另外,你经常只需要单一的工厂对象,因此在本历中它 被创建为Service实现中的一个static域。
10.7 嵌套类
如果不需要内部类对象与其外围类对象之间有联系,那么可以将内部类声明为static。这通常称为嵌套类。想要理解static应用于内部类时的含义,就必须记住,普通的内部类对象隐式的保 存了一个引用,指向创建它的外围类对象。然后,当内部类为static时,就不是这样了,
当内部类为static时,嵌套类意味着:
1)要创建嵌套类的对象,并不需要外围类的对象
2)不能从嵌套类的对象中访问非静态的外围类对象
普通内部类和嵌套类的另一个区别为:普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可 以包含所有这些东西。
package chapter10.innerclass;
import chapter10.Contents;
import chapter10.Destination;
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;
public ParcelDestination(String label){this.label=label;}
public String readLabel(){return label;}
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");
d.readLabel();
}
}
在一个普通(非static)的内部类中,通过一个特殊的this引用可以连接到外围类的对象。嵌套类中没有这个特殊的this引用,这使得它类似于一个static方法。
10.7.1 接口内部的类
正常情况下,不能在内部类中放置任何代码,但嵌套类可以作为接口的一部分。你放到接口中的任何类型都自动地是public和static的。只是将嵌套类置于接口的命名空间内,这并 不违反接口的规则。你甚至可以在内部类中实现其外围接口。如下:
package chapter10.innerclass;
public interface ClassInInterface {
void howdy();
class Test implements ClassInInterface{
public void howdy(){
System.out.println("-------");
}
public static void main(String[] args){
new Test().howdy();
}
}
}
如果你想创建公共代码,使得他们可以被某个接口的所有不同实现所共用,那么使用内部的嵌套类会显得很方便。
10.7.2 从多层嵌套中访问外部类的成员
一个内部类被嵌套多少层并不重要------它能透明地访问所有它所嵌入的外围类的所以成员。 如下所示:
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.7.2 从多层嵌套中访问外部类的成员
* @since 2013-06-24 16:14
* @author 张彪
*/
class MNA{
private void f(){}
class A{
private void g(){}
public class B{
void h(){
g();
f();
}
}
}
}
public class MultiNestingAccess {
public static void main(String[] args){
MNA m=new MNA();
MNA.A mnaa=m.new A(); //使用外部类.new来创建内部类对象
MNA.A.B mnab=mnaa.new B(); //使用外部类.new来创建内部类对象
mnab.h();
}
}
10.8 为什么需要内部类
使用内部类的原因:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没用影响。
10.5.1 闭包与回调
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。通过这个定义,可以看出内部类是面向对象的闭包,因为它不仅包含外围类对象的信 息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括Private成员。
Java最引人争议的问题之一就是,人们认为Java应该包含某种类似指针的机制。以允许回调。
package chapter10.innerclass;
interface Incrementable{ void increment();}
class Callee1 implements Incrementable{
private int i=0;
public void increment(){
i++;
System.out.println();
}
}
class MyIncrement{
public void increment(){System.out.println("Other operation");}
static void f(MyIncrement mi){mi.increment();}
}
class Callee2 extends MyIncrement{
private int i=0;
public void increment(){
super.increment();
i++;
System.out.println(i);
}
private class Closure implements Incrementable{
public void increment(){
Callee2.this.increment();
}
}
Incrementable getCallbackReference(){
return new Closure();
}
}
class Caller{
private Incrementable CallbackReference;
Caller(Incrementable cbh){this.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 call1=new Caller(c1);
Caller call2=new Caller(c2.getCallbackReference());
call1.go();
call2.go();
}
}
上面这个例子展示了外围类实现一个接口与内部类实现接口直接的区别。就代码而言,Callee1是简单的解决方法,Callee2继承MyIncrement类,并用内部类实现了Incrementable接口。
10.5.2 内部类与控制框架
在将要介绍的控制框架中(control framework)中,可以看到更多使用内部类的具体例子。
应用程序框架(application framework)就是被设计用于解决某类特定问题的一个类或一组类。
详见类chapter10\greenhouse\GreenHouseControllers.java
有关命令设计模式见类chapter10\greenhouse\GreenHouseController.java
10.9 内部类的继承
因为内部类的构造器必须连接到指向其外围类对象的引用,所以在继承内部类的时候,事情会变得有点复杂。问题在于,哪个执行外围类对象的“秘密的”引用必须被初始化,而在导出类中 不再存在可连接的默认对象。要解决这个问题,必须使用特殊的语法来说明他们之间的关系。
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.9 内部类的继承
* @since 2013-06-24 19:23
* @author 张彪
*/
class WithInner{
class Inner{}
}
public class InheritInner extends WithInner.Inner{
InheritInner(WithInner wi){
wi.super();
}
public static void main(String[] args){
WithInner w=new WithInner();
InheritInner h=new InheritInner(w);
}
}
可以 InheritInner类只是基础内部类,而不是外围类。但是当要生成一个构造器时,默认的构造器并不算好,而且不能只是传递一个指向外围类对象的引用 而已。此外,必须在构造器内部使用如下语法:
enclosingClassReference.super();
10.10 内部类可以被覆盖吗
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.10 内部类可以被覆盖吗
* @since 2013-06-24 19:34
* @author 张彪
*/
class Egg{
private Yolk y;
protected class Yolk{
public Yolk(){System.out.println("Egg.Yolk()");}
}
public Egg(){
System.out.println("New.Yolk()");
y=new Yolk();
}
}
public class BigEgg extends Egg{
public class Yolk{
public Yolk(){System.out.println("BigEgg.Yolk()");}
}
public static void main(String[] args){
BigEgg b=new BigEgg();
Yolk y=b.new Yolk();
}
}
/*New.Yolk()
Egg.Yolk()
BigEgg.Yolk()*/
注意:从输出的结果来看,符合程序的处理思维,个人认为是正常,但是好像书本上将的。。。。。。。有点晕。
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.10 明确继承某个内部类
* @since 2013-06-24 19:34
* @author 张彪
*/
class Egg2{
protected class Yolk{
public Yolk(){System.out.println("Egg2.Yolk()");}
public void f(){System.out.println("Egg2.Yolk.f()");}
}
private Yolk y=new Yolk();
public Egg2(){
System.out.println("New Egg2()");
}
public void insertYolk(Yolk yy){this.y=yy;}
public void g(){y.f();}
}
public class BigEgg2 extends Egg2{
public class Yolk extends Egg2.Yolk{ //明确地继承某个内部类
public Yolk(){System.out.println("BigEgg2.Yolk()");}
public void f(){System.out.println("BigEgg2.Yolk.f()");}
}
public BigEgg2(){
insertYolk(new Yolk());
}
public static void main(String[] args){
Egg2 e=new BigEgg2();
e.g();
}
}
/*Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()*/
P:上面这个例子的输出结果看的有点晕乎。。。。。。。
10.11 局部内部类
可以在代码块中创建内部类,典型的方式是在一个方法体的里面创建。局部内部类不能有访问说明符,因为它不是外部类的一部分;但是它可以访问当前代码块中的常量以及此外围类的所有成员。
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.11 局部类
* @since 2013-06-24 20:09
* @author 张彪
*/
interface Counter{
int next();
}
public class LocalInnerClass {
private int count=0;
Counter getCounter1(final String name){
//a local inner class
class LocalCounter implements Counter{
public LocalCounter(){
//local inner class can hava a constructor
System.out.print("LocalCounter()");
}
public int next(){
System.out.println(name);
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 hava a named
{
System.out.println("Counter2()");
}
public int next(){
return count++;
}
};
}
public static void main(String[] args){
LocalInnerClass l=new LocalInnerClass();
Counter c1=l.getCounter1("Local inner"),
c2=l.getCounter2("Anonymous inner");
for(int i=0;i<5;i++){
System.out.println(c1.next());
}
}
}
上例中我们分别使用局部内部类和匿名内部类实现了同样的功能,他们具有相同的行为和能力。既然局部内部类的名字在方法外是不可见的,那为什么我们仍然使用局部内部类 而不是匿名内部类呢?唯一的理由是:我们需要一个已命名的构造器,或者需要重载构造器,而匿名内部类只能用于实例初始化。
10.12 内部类标识
内部类的文件也必须是以.class文件格式,而且内部类的文件命名有严格的规则:外围类的名字,加上“$”再加上内部类的名字。例如
LocalInnerClass$1LocalCounter.class
Parcel11$ParcelDestination.class
Parcel11$ParcelDestination$AnotherLevel.class
10.13 总结
随着时间的推移,读者将能够更好的识别在什么情况下使用接口,什么情况下使用内部类,或者两者同时同时,此时你至少应该已经理解了他们的语法和语义。
Good Luck!!!
2013-06-24 20:43 记 @tangxiacun.tianhequ.guanzhou
第十章 内部类
可以将一个类的定义放在另一个类的定义内部,这就是内部类。
内部类允许你把一些逻辑相关的类组织在一起,并控制位于内部类的可见性。 内部类与组合不同。
10.1 创建内部类
创建内部类的方式就如你想的一样----把类的定义置于外围类的里面。
package chapter10;
/*@name RandomDoubles.java
* @describe 10.1 创建内部类
* @since 2013-06-23 16:59
* @author 张彪
*/
public class Parcel1 {
class Contents{
private int i=11;
public int value(){return i;}
}
class Desination{
private String label;
Desination(String label){this.label=label;}
String readLabel(){return label;}
}
public void ship(String dest){
Contents c=new Contents();
Desination d=new Desination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Parcel1 p=new Parcel1();
p.ship("Tasmania");
}
}
//当我们在ship()方法里面使用内部类的时候,与使用不同类没什么区别。在这里,实际的区别只是内部类的名字嵌套在Parel1里面的。更典型的情况是,外部类将有一个方法,方法返回一个指向内部类的引用,就像在to和contents()方法中看到的那样。
package chapter10;
/*@name RandomDoubles.java
* @describe 10.1 创建内部类
* @since 2013-06-23 16:59
* @author 张彪
*/
public class Parcel2 {
class Contents{
private int i=11;
public int value(){return i;}
}
class Desination{
private String label;
Desination(String label){
this.label=label;
}
String readLabel(){
return label;
}
}
public Desination to(String s){
return new Desination(s);
}
public Contents contents(){
return new Contents();
}
public void ship(String dest){
Contents c=new Contents();
Desination d=new Desination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Parcel2 p=new Parcel2();
p.ship("Tasmania");
Parcel2.Contents c=p.contents();
Parcel2.Desination d= p.to("Boring");
}
}
//如果想在外部类的非静态方法中之外的任何位置创建某个内部类的对象。那么必须在main()方法中那样,具体地指明这个对象的类型。OuterClassName.InnerClassName.
10.2 链接到外部类
到目前为止,内部类似乎还只是一种名字隐藏和组织代码的模式。这些是很有用,但还不是最引人注目的。当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联 系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其他外围类的所有元素的访问权限。(这与C++嵌套类的设计非常不同,在C++中只是单纯的名字隐藏 机制,与外围对象没有联系)
package chapter10;
/*@name Sequence.java
* @describe 10.2 链接到外部类
* @since 2013-06-23 17:48
* @author 张彪
*/
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 s=new Sequence(10);
for(int i=0;i<10;i++){
s.add(Integer.toString(i));
}
Selector selector=s.selector();
while(!selector.end()){
System.out.println(selector.current());
selector.next();
}
}
}
注意:内部类自动拥有对外围类所有成员的访问权限。这是如何做到的呢?当某个外围类的对象创建了一个内部类对象是,此内部类对象必定会秘密地捕获一个指向那个外围类的引用。
10.3 使用.this和.new
10.3.1 .this的用法
如果你需要生成对外边对象的引用,可以使用外边类的名字后面紧跟圆点和this。这样产生的引用自动地具有正确的类型。
package chapter10;
/*@name DotThis.java
* @describe 10.3 使用.this和.new
* @since 2013-06-23 17:48
* @author 张彪
*/
public class DotThis {
void f(){System.out.println("DotThis.f()");}
public class Inner{
public DotThis outer(){
return DotThis.this; //注意:this的使用
}
}
public Inner inner(){
return new Inner();
}
public static void main(String[] args){
DotThis d=new DotThis();
DotThis.Inner n= d.inner();
n.outer().f();
}
}
10.3.2 .new的用法
有时你可能要告知某些其他对象,去创建其某个内部类的对象。要实现此目的,你必须在new表达式中提供对其他外部对象的引用,这是需要使用.new语法。例如:
package chapter10;
/*@name DotNew.java
* @describe 10.3 使用.this和.new
* @since 2013-06-23 18:48
* @author 张彪
*/
public class DotNew {
public class Inner{}
public static void main(String[] args){
DotNew dn=new DotNew();
DotNew.Inner n=dn.new Inner(); //注意.new的用法
//dn.new DotNew.Inner(); 不能这样声明
//Inner r=new Inner(); 也不能这样声明
}
}
要想直接创建内部类的对象,必须使用外部类的对象来创建内部类对象。这样解决了内部类名字作用域的问题。因此你不必声明(实际上你不能声明)dn.new DotNew.Inner()
10.3.4 嵌套类(静态内部类)
在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地链接到创建它的外部类对象上。但是如果你创建的是嵌套类(静态内部类),那么它就不需 要对外部类对象的引用。
package chapter10;
/*@name DotNew.java
* @describe 10.3 嵌套类(静态内部类)
* @since 2013-06-23 19:11
* @author 张彪
*/
public class Pracel3 {
class Contents{
private int i=11;
public int value(){return i;}
}
class Destination{
private String label;
Destination(String whereTo){this.label=whereTo;}
String readLabel(){return label;}
}
public static void main(String[] args){
//Must use instance of outer class to create an instance of the inner class
Pracel3.Contents c=(new Pracel3()).new Contents();
Pracel3.Destination d=(new Pracel3()).new Destination("Tasmania");
}
}
10.4 内部类和向上转型
当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地。(从实现了某个接口的对象,得到对此接口的引用,与向上转型为这个对象的基类,实质上效 果是一样的。)这是因为此内部类--某个接口的实现--能够完全不可见,并且不可用。所得到的只是指向基类或接口的引用,所以能够很方便地隐藏实现的细节。
我们可以创建前一个示例的接口:
package chapter10;
import chapter10.Contents;
import chapter10.Destination;
public class Pracel4 {
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 label){this.label=label;}
public String readLabel(){return label;}
}
public Destination destination(String s){
return new PDestination(s);
}
public Contents contents(){
return new PContents();
}
public static void main(String[] args){
Pracel4 p=new Pracel4();
Destination pd= p.destination("Tasmania");
Contents c=p.contents();
Pracel4.PContents pc= p.new PContents(); //在同一个类就可以这样访问;若在不同类中,则不能访问私有类。
}
}
10.5 在方法和作用域内的内部类
到目前为止,所见的都是“平凡的”内部类,简单而且容易理解。然而,内部类的语法覆盖了大量的其他的更加难以理解的技术。例如。可以在一个方法里面或者在任意作用域内定义 内部类。这么做有两个理由:
1)如前所示,你实现了某类型的接口,于是可以创建并返回对其引用。
2)你要解决一个复杂的问题,想创建一个类用来辅助你的解决方案,但又不希望这个类是公共可用的。
下面的例子,先前的代码将被修改,以用于实现:
1)一个定义在方法中的类
2)一个定义在作用域中的类,此作用域在方法的内部
3)一个实现了接口的匿名类
4)一个匿名类,它扩展了有非默认构造器的类
5)一个匿名类,它执行字段初始化
6)一个匿名类,它通过实例初始化实现构造(匿名类不可能有构造器)
下面这个例子展示了在方法的作用域内(而不是在其他类的作用域内)创建一个完整的类。这称为局部内部类。
package chapter10;
import chapter10.Pracel4.PDestination;
/*@name DotNew.java
* @describe 10.5 在方法的作用域内(而不是在其他类的作用域内)创建一个完整的类。这称为局部内部类。
* @since 2013-06-23 22:49
* @author 张彪
*/
public class Parcel5 {
public Destination destination(String s){
class PDestination implements Destination{
private String label;
private PDestination(String whereTo){this.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");
System.out.println(d.readLabel());
}
}
10.5.1 在任意的作用域内嵌入一个内部类
package chapter10;
/*@name DotNew.java
* @describe 10.5 如何在任意的作用域内嵌入一个内部类
* @since 2013-06-23 22:49
* @author 张彪
*/
public class Parcel6 {
private void internalTracking(boolean b){
if(b){
class TrackingSlip{
private String id;
TrackingSlip(String id){this.id=id;}
String getSlip(){return id;}
}
TrackingSlip ts=new TrackingSlip("slip");
String s=ts.getSlip();
}
}
public void track(){internalTracking(true);}
public static void main(String[] args){
Parcel6 p=new Parcel6();
p.track();
}
}
TrackingSlip类被嵌入在if语句的作用域内,这并不是说该类的创建是有条件的,它其实与别的类一起编译过了。
10.6 匿名内部类
看下面的这个例子看起来有点奇怪哦:
package chapter10;
/*@name DotNew.java
* @describe 10.7 匿名内部类
* @since 2013-06-24 9:00
* @author 张彪
*/
public class Parcel7 {
public Contents contents(){
return new Contents(){ //insert a class definition
private int i=11;
public int value(){return i;}
};
}
public static void main(String[] args){
Parcel7 p=new Parcel7();
Contents s =p.contents();
System.out.print(s.value());
}
}
contents()方法将返回值的生成与表示这个返回值的类的定义结合在一起!另外这个类是匿名的,它没有名字,更糟的是,看起来似乎是你正要创建一个Contents对象。但是然后你却说:"等一等,我想在这里插入一个类的定义。"
这种奇怪的语法指的是:“创建一个继承自Contents的匿名类的对象。”通过new表达式返回的引用被自动向上转型为对Contents的引用。
上述匿名内部类的语法是下述形式的简化形式:
package chapter10;
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 s =p.contents();
System.out.print(s.value());
}
}
在匿名内部类中定义字段并执行初始化操作:
package chapter10;
/*@name DotNew.java
* @describe 10.6 匿名内部类中定义字段并执行初始化操作
* @since 2013-06-24 9:00
* @author 张彪
*/
public class Parcel9 {
public Destination destination(final String dest){
return new Destination(){
private String label=dest;
public String readLabel(){return dest;}
};
}
public static void main(String[] args){
Parcel9 p=new Parcel9();
Destination d=p.destination("Timanis");
System.out.println(d.readLabel());
}
}
注意:如果定义了一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译会要求其参数引用的是final的。如上例destination()方法,否则编译器会报错。
package chapter10;
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 bugget!");}
}
private String label=dest;
public String readLabel(){return label;}
};
}
public static void main(String[] args){
Parcel10 p=new Parcel10();
Destination d=p.destination("Tamanis", 120);
}
}
匿名内部类与正规的继承相比有些受限,因为匿名内部类既可以扩展类,也可以实现接口,但是不能两者兼备。而且是如果实现了接口,也只能实现一个接口。
10.6.1 再访工厂方法
看看在使用内部类时,Factory实例变得多么美妙呀:
package chapter10;
/*@name DotNew.java
* @describe 10.6.1 再访工厂方法
* @since 2013-06-24 14:52
* @author 张彪
*/
interface Service{
void method1();
void method2();
}
interface ServiceFactory{
Service getService();
}
class Implementation1 implements Service{
private Implementation1(){}
public void method1(){System.out.println("Implementation1.method1()");}
public void method2(){System.out.println("Implementation1.method2()");}
public static ServiceFactory factory=new ServiceFactory(){
public Service getService(){
return new Implementation1();
}
};
}
class Implementation2 implements Service{
private Implementation2(){}
public void method1(){System.out.println("Implementation2.method1()");}
public void method2(){System.out.println("Implementation2.method2()");}
public static ServiceFactory factory=new ServiceFactory(){
public Service getService(){
return new Implementation2();
}
};
}
public class Factories {
public static void serviceConsumer(ServiceFactory factory){
Service s=factory.getService();
s.method1();
s.method2();
}
public static void main(String[] args){
serviceConsumer(Implementation1.factory);
serviceConsumer(Implementation2.factory);
}
}
现在用于Implementation1和Implementation2的构造器都可以是private的,并且没有必要去创建作为工厂的具体名。另外,你经常只需要单一的工厂对象,因此在本历中它 被创建为Service实现中的一个static域。
10.7 嵌套类
如果不需要内部类对象与其外围类对象之间有联系,那么可以将内部类声明为static。这通常称为嵌套类。想要理解static应用于内部类时的含义,就必须记住,普通的内部类对象隐式的保 存了一个引用,指向创建它的外围类对象。然后,当内部类为static时,就不是这样了,
当内部类为static时,嵌套类意味着:
1)要创建嵌套类的对象,并不需要外围类的对象
2)不能从嵌套类的对象中访问非静态的外围类对象
普通内部类和嵌套类的另一个区别为:普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可 以包含所有这些东西。
package chapter10.innerclass;
import chapter10.Contents;
import chapter10.Destination;
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;
public ParcelDestination(String label){this.label=label;}
public String readLabel(){return label;}
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");
d.readLabel();
}
}
在一个普通(非static)的内部类中,通过一个特殊的this引用可以连接到外围类的对象。嵌套类中没有这个特殊的this引用,这使得它类似于一个static方法。
10.7.1 接口内部的类
正常情况下,不能在内部类中放置任何代码,但嵌套类可以作为接口的一部分。你放到接口中的任何类型都自动地是public和static的。只是将嵌套类置于接口的命名空间内,这并 不违反接口的规则。你甚至可以在内部类中实现其外围接口。如下:
package chapter10.innerclass;
public interface ClassInInterface {
void howdy();
class Test implements ClassInInterface{
public void howdy(){
System.out.println("-------");
}
public static void main(String[] args){
new Test().howdy();
}
}
}
如果你想创建公共代码,使得他们可以被某个接口的所有不同实现所共用,那么使用内部的嵌套类会显得很方便。
10.7.2 从多层嵌套中访问外部类的成员
一个内部类被嵌套多少层并不重要------它能透明地访问所有它所嵌入的外围类的所以成员。 如下所示:
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.7.2 从多层嵌套中访问外部类的成员
* @since 2013-06-24 16:14
* @author 张彪
*/
class MNA{
private void f(){}
class A{
private void g(){}
public class B{
void h(){
g();
f();
}
}
}
}
public class MultiNestingAccess {
public static void main(String[] args){
MNA m=new MNA();
MNA.A mnaa=m.new A(); //使用外部类.new来创建内部类对象
MNA.A.B mnab=mnaa.new B(); //使用外部类.new来创建内部类对象
mnab.h();
}
}
10.8 为什么需要内部类
使用内部类的原因:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没用影响。
10.5.1 闭包与回调
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。通过这个定义,可以看出内部类是面向对象的闭包,因为它不仅包含外围类对象的信 息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括Private成员。
Java最引人争议的问题之一就是,人们认为Java应该包含某种类似指针的机制。以允许回调。
package chapter10.innerclass;
interface Incrementable{ void increment();}
class Callee1 implements Incrementable{
private int i=0;
public void increment(){
i++;
System.out.println();
}
}
class MyIncrement{
public void increment(){System.out.println("Other operation");}
static void f(MyIncrement mi){mi.increment();}
}
class Callee2 extends MyIncrement{
private int i=0;
public void increment(){
super.increment();
i++;
System.out.println(i);
}
private class Closure implements Incrementable{
public void increment(){
Callee2.this.increment();
}
}
Incrementable getCallbackReference(){
return new Closure();
}
}
class Caller{
private Incrementable CallbackReference;
Caller(Incrementable cbh){this.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 call1=new Caller(c1);
Caller call2=new Caller(c2.getCallbackReference());
call1.go();
call2.go();
}
}
上面这个例子展示了外围类实现一个接口与内部类实现接口直接的区别。就代码而言,Callee1是简单的解决方法,Callee2继承MyIncrement类,并用内部类实现了Incrementable接口。
10.5.2 内部类与控制框架
在将要介绍的控制框架中(control framework)中,可以看到更多使用内部类的具体例子。
应用程序框架(application framework)就是被设计用于解决某类特定问题的一个类或一组类。
详见类chapter10\greenhouse\GreenHouseControllers.java
有关命令设计模式见类chapter10\greenhouse\GreenHouseController.java
10.9 内部类的继承
因为内部类的构造器必须连接到指向其外围类对象的引用,所以在继承内部类的时候,事情会变得有点复杂。问题在于,哪个执行外围类对象的“秘密的”引用必须被初始化,而在导出类中 不再存在可连接的默认对象。要解决这个问题,必须使用特殊的语法来说明他们之间的关系。
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.9 内部类的继承
* @since 2013-06-24 19:23
* @author 张彪
*/
class WithInner{
class Inner{}
}
public class InheritInner extends WithInner.Inner{
InheritInner(WithInner wi){
wi.super();
}
public static void main(String[] args){
WithInner w=new WithInner();
InheritInner h=new InheritInner(w);
}
}
可以 InheritInner类只是基础内部类,而不是外围类。但是当要生成一个构造器时,默认的构造器并不算好,而且不能只是传递一个指向外围类对象的引用 而已。此外,必须在构造器内部使用如下语法:
enclosingClassReference.super();
10.10 内部类可以被覆盖吗
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.10 内部类可以被覆盖吗
* @since 2013-06-24 19:34
* @author 张彪
*/
class Egg{
private Yolk y;
protected class Yolk{
public Yolk(){System.out.println("Egg.Yolk()");}
}
public Egg(){
System.out.println("New.Yolk()");
y=new Yolk();
}
}
public class BigEgg extends Egg{
public class Yolk{
public Yolk(){System.out.println("BigEgg.Yolk()");}
}
public static void main(String[] args){
BigEgg b=new BigEgg();
Yolk y=b.new Yolk();
}
}
/*New.Yolk()
Egg.Yolk()
BigEgg.Yolk()*/
注意:从输出的结果来看,符合程序的处理思维,个人认为是正常,但是好像书本上将的。。。。。。。有点晕。
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.10 明确继承某个内部类
* @since 2013-06-24 19:34
* @author 张彪
*/
class Egg2{
protected class Yolk{
public Yolk(){System.out.println("Egg2.Yolk()");}
public void f(){System.out.println("Egg2.Yolk.f()");}
}
private Yolk y=new Yolk();
public Egg2(){
System.out.println("New Egg2()");
}
public void insertYolk(Yolk yy){this.y=yy;}
public void g(){y.f();}
}
public class BigEgg2 extends Egg2{
public class Yolk extends Egg2.Yolk{ //明确地继承某个内部类
public Yolk(){System.out.println("BigEgg2.Yolk()");}
public void f(){System.out.println("BigEgg2.Yolk.f()");}
}
public BigEgg2(){
insertYolk(new Yolk());
}
public static void main(String[] args){
Egg2 e=new BigEgg2();
e.g();
}
}
/*Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()*/
P:上面这个例子的输出结果看的有点晕乎。。。。。。。
10.11 局部内部类
可以在代码块中创建内部类,典型的方式是在一个方法体的里面创建。局部内部类不能有访问说明符,因为它不是外部类的一部分;但是它可以访问当前代码块中的常量以及此外围类的所有成员。
package chapter10.innerclass;
/*@name DotNew.java
* @describe 10.11 局部类
* @since 2013-06-24 20:09
* @author 张彪
*/
interface Counter{
int next();
}
public class LocalInnerClass {
private int count=0;
Counter getCounter1(final String name){
//a local inner class
class LocalCounter implements Counter{
public LocalCounter(){
//local inner class can hava a constructor
System.out.print("LocalCounter()");
}
public int next(){
System.out.println(name);
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 hava a named
{
System.out.println("Counter2()");
}
public int next(){
return count++;
}
};
}
public static void main(String[] args){
LocalInnerClass l=new LocalInnerClass();
Counter c1=l.getCounter1("Local inner"),
c2=l.getCounter2("Anonymous inner");
for(int i=0;i<5;i++){
System.out.println(c1.next());
}
}
}
上例中我们分别使用局部内部类和匿名内部类实现了同样的功能,他们具有相同的行为和能力。既然局部内部类的名字在方法外是不可见的,那为什么我们仍然使用局部内部类 而不是匿名内部类呢?唯一的理由是:我们需要一个已命名的构造器,或者需要重载构造器,而匿名内部类只能用于实例初始化。
10.12 内部类标识
内部类的文件也必须是以.class文件格式,而且内部类的文件命名有严格的规则:外围类的名字,加上“$”再加上内部类的名字。例如
LocalInnerClass$1LocalCounter.class
Parcel11$ParcelDestination.class
Parcel11$ParcelDestination$AnotherLevel.class
10.13 总结
随着时间的推移,读者将能够更好的识别在什么情况下使用接口,什么情况下使用内部类,或者两者同时同时,此时你至少应该已经理解了他们的语法和语义。
Good Luck!!!
2013-06-24 20:43 记 @tangxiacun.tianhequ.guanzhou
- chapter10.rar (12.9 KB)
- 下载次数: 1
发表评论
-
第十三章 字符串
2013-08-06 00:50 9382013年8月1日 星期四 21时05分59秒 第十三章 字 ... -
第十二章 通过异常处理错误
2013-08-01 21:04 7592013年7月10日 星期三 00时04分21秒 第十二章 ... -
第十一章 持有对象
2013-07-09 00:49 9562013年6月24日 星期一 20时57分09秒 第十一章 ... -
第十四章 类型信息
2013-07-02 01:26 9562013年6月25日 星期二 23时12分42秒 第十四章 ... -
第九章 接口
2013-06-23 16:46 8782013年6月20日 星期四 21时41分40秒 第九章 接 ... -
第八章 多态
2013-06-19 23:06 7052013年6月17日 星期一 23 ... -
Thinking in Java Fourth Edition Source Code
2013-06-17 23:10 526Thinking in Java F ... -
第七章 复用类
2013-06-17 22:36 5932013年6月16日 星期日 21时06分54秒 第七章 复 ... -
第六章 访问权限控制
2013-06-16 21:05 8882013年6月16日 星期日 11时10分46秒 第六章 访 ... -
第五章 初始化与清理
2013-06-16 10:58 6332013年6月15日 星期六 16 ...
相关推荐
严蔚敏教授的《数据结构》是一本经典的教材,其中第十章专门讲解了内部排序算法。内部排序,指的是数据在计算机内存中进行的排序过程,相对于外部排序,其处理的数据量相对较小,但要求快速、高效。 在这一章中,...
### 第十章 类与对象 —— C++ 重难点知识详解 #### 一、引言 C++ 是一种广泛应用于工业界的编程语言,它既继承了 C 语言的强大功能,又引入了面向对象编程(OOP)的概念。面向对象编程的核心在于类与对象的设计与...
在这个"JavaScript第十章完整案例"中,我们将会探索北大青鸟课程体系中关于JavaScript的高级应用和实战项目,这将帮助我们理解如何将理论知识转化为实际操作。 在JavaScript的第十章,通常会涵盖诸如DOM操作、事件...
第十章主要探讨的是内部排序,这是数据结构领域中一个核心的话题。内部排序指的是在计算机内存中完成的排序过程,适用于数据量相对较小的情况。本章的学习目标包括掌握各种排序算法的原理、特点、排序过程以及时间...
根据给定的文件信息,以下是对“万博内部教材第十章”的详细解读,主要涉及恶意代码的概念、起源、解决方法以及具体实例。 ### 恶意代码概述 恶意代码是指故意设计用于非法侵入计算机系统、破坏数据或干扰正常运行...
《C++ Primer Plus》是C++编程领域里一本广受欢迎的教材,它的第十章主要讲解了C++中的类和对象,这是C++的核心概念之一。在这个章节中,你会接触到类的定义、对象的创建与使用、封装、继承、多态等关键知识点。现在...
数据结构中的内部排序是计算机科学中一种重要的概念,主要针对的是在内存中处理的数据集合,目的是将无序的记录序列调整为有序。本课件主要介绍了内部排序的多个方法及其特性。 1. **概述** - **排序定义**:排序...
综上所述,C++大学教程第四版第十章主要介绍了常对象与常成员函数、对象的组合、友元函数与类、this指针的使用、动态内存管理以及静态类成员等内容。这些知识点对于理解和掌握面向对象编程的基本概念和技术至关重要...
严蔚敏版《数据结构》是一本经典的教材,其中第十章主要探讨了内部排序算法,这是对大量数据进行排序时常用的一类方法。 内部排序指的是在整个排序过程中,数据完全在内存中进行处理,不需要借助外部存储设备。这一...
会计系统与内部控制是企业管理的核心组成部分,特别是在信息技术高度发达的今天,它们的作用更加凸显。会计系统是企业收集、处理、存储和报告财务信息的关键工具,而内部控制则是保障会计信息准确、完整和安全的重要...
本资料"基础会计第十章会计凭证.zip"包含了对会计凭证的深入讲解,旨在帮助学习者理解和掌握会计凭证的原理与操作流程。在这个压缩包中,主要包含了一个名为"基础会计第十章会计凭证.pptx"的文件,它可能是一个详细...
第九章和第十章的作业1主要涉及磁性和材料科学的相关概念。下面将详细解释这些知识点。 9.2 磁性产生的根本原因在于原子中电子的运动产生电流,形成了电子自旋和轨道磁矩。在某些元素如Fe、Co、Ni中,由于内部强烈...
《C++程序设计教程:第十章 继承》 继承是面向对象编程中的核心概念,它允许一个类(称为派生类或子类)从另一个类(称为基类或父类)继承特性,从而实现代码的重用和扩展。本章主要介绍了C++中的继承结构、访问...
### Python基础第十章知识点详解 #### 一、模块与客户端 **1. 模块化程序设计的概念** - **模块化程序设计**: 当程序变得庞大且包含多种可复用的功能时,通常会把这些功能组织成不同的模块。一个模块包含了相关...
AsyncTask允许在后台线程执行任务,同时在UI线程更新结果,其内部也使用了Handler和Looper。使用AsyncTask时,需要定义三个泛型参数,分别代表输入参数、执行过程中的进度类型和最终结果类型。 服务的生命周期包括...
以上是自考审计学第十章的主要知识点,涵盖了筹资与投资循环的特性、涉及的财务报表项目、业务活动、凭证记录、内部控制测试以及审计方法。理解和掌握这些知识点对于理解企业资金流动和风险管理至关重要。
### 第十章 传输层 #### 10.1 传输层基础 ##### 10.1.1 划分传输层的必要性 在计算机网络的层次结构中,传输层占据了一个非常特殊的位置。一方面,它作为面向通信子网的最高层,与下三层共同构建了网络通信所需的...