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. 关于datatime 时间处理模块:

    import time        from datetime import datetime        from datetime import timedelta        aHour= ...

  2. OOP: One pont of view of OOP与基于算法设计的区别

    ..摘自<C++网络编程 卷1:运用ACE和模式消除复杂性> <C++ Network Programming Volume 1 Mastering Complexity with ...

  3. 【Oracle】Oracle 序列步长问题

    问题: 数据库中客户表的ID 变化为 21\31\41 有序数字,而不是1\2\3 依次增长 [问题原因]: SEQ_CUSTOMNOTEEN 设置了缓存20,每次取20个数,然后一个一个给你,如果中 ...

  4. 【Telerik】<telerik:RadGridView/>控件的使用

    学习Telerik第三方控件中的WPF时,对于RadGridView控件做的一些记录. AutoGenerateColumns:启动时是否生成列 ShowGroupPanel:是否显示表格的分组名称 ...

  5. myString操作符重载

    写在前面的话: 重载是C++的重要内容,在自定义一个类的时候,需要对类中的方法进行重载,才能方便的实现相应的功能,比如一些运算符,构造,析构函数,一些功能函数等等,而C++语言自带的这些东西只使用于基 ...

  6. [sourceTree]这是一个无效的源路径

    解决方法:工具 ——>选项  ——> git, 启用git 就可以了.

  7. CSS3过渡、变形和动画

    1.CSS3过渡 所谓CSS3过渡,就是使用CSS3让元素从一种状态慢慢转换到另一种状态.如鼠标的悬停状态就是一种过渡.如下例子: #content a{     text-decoration: n ...

  8. 百度地图 获取两点坐标之间的驾车距离(非直线距离) c#

    百度接口了解: http://lbsyun.baidu.com/index.php?title=webapi/route-matrix-api-v2 起点与终点为多对多关系,如果你只想取两个坐标,那就 ...

  9. Ubuntu ssh服务安装

    在使用xshell连接ubuntu虚拟机时,提示 Could not connect to '192.168.0.106' (port 22): Connection failed. 在主机使用pin ...

  10. Oracle数据库基础知识1

    DDL语句 1.表的创建 CREATE TABLE table_name(); 例如: CREATE TABLE USER_E( id NUMBER (5), name VARCHAR(20), ge ...