Reusing Classes

有两种常用方式实现类的重用,组件(在新类中创建存在类的对象)和继承。

Composition syntax

Every non-primitive object has a toString() method, and it’s called in special situations when the compiler wants a String but it has an object.

Inheritance syntax

You’re always doing inheritance when you create a class, because unless you explicitly inherit from some other class, you implicitly inherit from Java’s standard root class Object.

To allow for inheritance, as a general rule make all fields private and all methods public. Of course, in particular cases you must adjustments, but this is a useful guideline.

|_Initializing the base class

Even if you don’t create a constructor for derived-class, the compiler will synthesize a default constructor for you that calls the base constructor.

If your class doesn’t have default arguments, or if you want to call a base-class constructor that has an argument, you must explicitly write the calls to the base-class constructor using the super keyword and the appropriate argument list. In addition, the call to the base-class constructor must be the first thing you do in the derived-class constructor.

Delegation

委托是重用类的第三种方式,介于继承和组件之间。在新建类中放置成员对象(像组件),同时暴露该对象的所有方法(像继承)。You have more control with delegation because you can choose to provide only a subset of the methods in the member object.

Combining composition and inherit

|_Guaranteeing proper cleanup

Note that in your cleanup method, you must also pay attention to the calling order for the base-class and member-object cleanup methods in case one subobject depends on another. In general, you should follow the same form that is imposed by a C++ compiler on its destructors: First perform all of the cleanup work specific to your class, in the reverse order of creation.

There can be many cases in which the cleanup issue is not a problem; you just let the garbage collector do the work. But when you must do it explicitly, diligence and attention are required, because there’s not much you can rely on when it comes to garbage collection. The garbage collector might never be called. If it is, it can reclaim objects in any order it wants. You can’t rely on garbage collection for anything but memory reclamation. If you want cleanup to take place, make your own cleanup methods and don’t use on finalize().

Choosing composition vs. inheritance

Both composition and inheritance allow you to place subobject inside your new class(composition explicitly does this-with inheritance it’s implicit).

The is-a relationship is expressed with inheritance, and the has-a relationship is expressed with composition.

Upcasting

In object-oriented programming, the most likely way that you’ll create and use code is by simply packaging data and methods together into a class, and using objects of that class. You’ll also use existing classes to build new classes with composition. Less frequently, you’ll use inheritance. So although inheritance gets a lot of emphasis while learning OOP, it doesn’t mean that you should use it everywhere you possibly can. On the contrary, you should use it sparingly, only when it’s clear that inheritance is useful. One of the clearest ways to determine whether you should use composition or inheritance is to ask whether you’ll ever need to upcast from your new class to the base class. If you must upcast, then inheritance is necessary. The Polymorphism provides one of the most compelling reasons for upcasting, but if you remember to ask “Do I need to upcast?” you’ll hava a good tool for deciding between composition and inheritance.

The final keyword

There are there places where final can be used: for data, methods and classes.

|_final data

That a piece of data is constant is useful for two reasons:

1. It can be a compile-time constant that won’t ever change.

2. It can be a value initialized at run time that you don’t want changed.

In the case of a compile-time constant, the compiler is allowed to “fold” the constant value into any calculations in which it’s used; that is, the calculation can be performed at compile time, eliminating some run-time overhead. In Java, these sorts of constants must be primitives and are expressed with the final keyword. A value must be given at the time of definition of such a constant.

当final被用于对象引用上时,对象的引用不能被更改,即该引用不能指向其他对象,但是对象本身可以被修改。这个规则对隶属于对象的数组引用同样适用。

在定义时不赋初值的final变量必须在使用之前被初始化(比如在构造体中初始化,static final不能在构造体中初始化,因为static不依赖于对象而存在),否则编译报错。You’re forced to perform assignments to finals either with an expression at the point of definition of the field or in every constructor. That way it’s guaranteed that the final field is always initialized before use.

|_final arguments

参数被final修饰时可读不可写。This feature is primarily used to pass data to anonymous inner classes.

|_final methods

用final修饰的方法不能被重写。

|_final and private

Any private methods in a class are implicitly final. Because you can’t access a private method, you can’t override it. You can add the final specifier to a private method, but it doesn’t give that method any extra meaning.

“Overriding” can only occur if something is part of the base-class interface. That is, you must be able to upcast an object to its base type and call the same method. If a method is private, it isn’t part of the base-class interface. It is just some code that’s hidden away inside the class, and it just happens to hava the name, but if you create a public, protected, or package-access method with the same name in the derived class, there’s no connection to the method that might happen to have that name in the base class. You haven’t overridden the method; you’ve just created a new method. Since a private method is unreachable and effectively invisible, it doesn’t factor into anything except for the code organization of the class for which it was defined.

|_final classes

When you say that an entire class is final(by preceding its definition with the final keyword), you state that you don’t want to inherit from this class or allow anyone else to do so. In other words, for some reason the design of your class is such that there is never a need to make any changes, or for safety or security reasons you don’t want subclassing.

Note that the field of a final class can be final or not, as you choose. The same rules apply to final for fields regardless of whether the class is defined as final. However, because it prevents inheritance, all methods in a final class are implicitly final, since there’s no way to override them. You can add the final specifier to a method in a final class, but it doesn’t add any meaning.

Initialization and class loading

In Java, the compiled code for each class exists in its own separate file. That file isn’t loaded until the code is needed. In general, you can say that “class code is loaded at the point of first use.” This is usually when the first object of that class is constructed, but loading also occurs when a static field or static method is accessed(The constructor is also a static methods even though the static keyword is not explicit. So to be precise, a class is first loaded when any one of its static members is accessed.).

|_Initialization with inheritance

第一次运行主类的main方法时,装载器找到该类对应的class文件,在装载的过程中如果发现它有父类,则继续装载其父类,父类还有父类,继续装载。接下来,在根类开始执行静态初始化,接下来是其派生类,等等。这是重要的,因为派生类静态初始化可能依赖父类成员被合理的初始化。

At this point, the necessary classes hava all been loaded so the object can be created. First, all the primitives in this object are set to their default values and the object references are set to null-this happens in one fell swoop by setting the memory in the object to binary zero. Then the base-class constructor will be called. In this case the call is automatic, but you can also specify the base-class constructor call by using super. The base class construction goes through the same process in the same order as the derived-class constructor. After the base-class constructor completes, the instance variables are initialized in textual order. Finally, the rest of the body of the constructor is executed.

Summary

Both inheritance and composition allow you to create a new type from existing types. Composition reuses existing types as part of the underlying implementation of the new type, and inheritance reuses the interface.

(END_XPJIANG)

 

TIJ——Chapter Seven:Reusing Classes的更多相关文章

  1. TIJ——Chapter Ten:Inner Classes

    先提纲挈领地来个总结: 内部类(Inner Class)有四种: member inner class,即成员内部类.可以访问外部类所有方法与成员变量.生成成员内部类对象的方法:OuterClass. ...

  2. TIJ——Chapter One:Introduction to Objects

    ///:~容我对这个系列美其名曰"读书笔记",其实shi在练习英文哈:-) Introduction to Objects Object-oriented programming( ...

  3. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(八)之Reusing Classes

    The trick is to use the classes without soiling the existing code. 1. composition--simply create obj ...

  4. TIJ——Chapter Eleven:Holding Your Objects

    Java Provides a number of ways to hold objects: An array associates numerical indexes to objects. It ...

  5. TIJ——Chapter Two:Everything Is an Object

    If we spoke a different language, we would perceive a somewhat different world. Ludwig Wittgenstein( ...

  6. Chapter 3 Discovering Classes and Object

    Chatper 3 Discovering Classes and Object Exercises: 1.What is a class? A class is a template for man ...

  7. TIJ——Chapter Fourteen:Type Information

    Runtime type information(RTTI) allows you to discover and use type information while a program is ru ...

  8. TIJ——Chapter Twelve:Error Handling with Exception

    Exception guidelines Use exceptions to: Handle problems at the appropriate level.(Avoid catching exc ...

  9. TIJ——Chapter Nine:Interfaces

    A class containing abstract methods is called an abstract class. If a class Contains one of more abs ...

随机推荐

  1. windows 2008 server NTP Server

    1. 选择一台服务器作为时间同步服务器. 2. 运行Regedit,打开注册表编辑器. 3. 找到注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Ser ...

  2. 设置R启动时自动加载常用的包或函数

    在我前面的文章(http://www.cnblogs.com/homewch/p/5749850.html)中有提到R可以自定义启动环境,需要修改R安装文件中的ect文件夹下的配置文件Rprofile ...

  3. jesperreport+ireport简单理解

    ireport:主要是生成报表模板 jesperreport:主要是用.jesper文件填充数据(jdbc.javabean)生成面向用户的文件(PDF.HTML等)

  4. Django分析之三级下拉菜单选择省/市/县

    今天遇到了一个一直想做却没有机会去做的功能,今天完成了便记录下来. 那这次是具体是个什么功能呢?其实还是很简单的效果,就是在用户注册的时候可以选择省/市/县,很简单的一个小功能. 那现在就开始了~首先 ...

  5. js性能优化-事件委托

    js性能优化-事件委托 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(当然只是一个解释,实际工作中很少 ...

  6. iOS二维码生成-libqrencode编译报错

    libqrencode使用 1.将libqrencode文件夹整个拖入项目文件夹中 2.在要生成二维码的页面的 .m文件头部添加 #import "QRCodeGenerator.h&quo ...

  7. MySQL模糊查询

    第一种最土的方法:使用like语句第二种用全文索引 有两种方法,第一种最土的方法:使用like语句第二种听涛哥说用全文索引,就在网上搜一下: 如何在MySQL中获得更好的全文搜索结果 mysql针对这 ...

  8. union

    union是C++中一个类,平时自己用的比较少,了解了一些特性后觉得在内存要求比较高的地方还是大有可为,总结一下. C++中的struct和union内部都可以定义 数据 和 函数, 两个跟 clas ...

  9. html5新特性

    这一篇博文不会告诉你怎么去使用html5的新特性,只会给你总结一下新特性------对于好学的人可以把这篇文章当做一个目录 对于初接触的人来说是一个导向 对于已经接触过的人来说是一个检测你掌握程度的检 ...

  10. 重新用delphi7写东西

    晚上开始写通讯录的程序,又对表进行点修改.重新开始用delphi7很不习惯,太不好用了. TArecord=record Const UserName=’YHName’; ..... End; 这个在 ...