The genesis of the computer revolution was a machine. The genesis of out programming languages thus tends to look like that machine.
计算机革命起源于机器,因此编程语言的产生也始于对机器的模仿
Computers are mind amplification tools and a different kind of expressive medium. 计算机是大脑延伸的工具,还是一种不同类型的表达媒体。
Object-oriented programming(OOP) is part of this movement toward using the computer as an expressive medium.
面向对象编程是这种把计算机作为表达媒体的大趋势的组成部分
The chapter is background and supplementary material.
there are many concepts that are introduced here to give you a solid overview of OOP.
Many people do not feel confortable wading into object-oriented programming without understanding the big picture first. However, other people may not get the big picture concepts until they‘ve seen some of the mechanics first.
The progress of absraction
It can be argued that the complexity of the problems you‘re able to solve is directly related to the kind and quality of abstraction.
Assembly language is a small abstraction of the underlying machine
Many so-called "imperative" languages that followed (such as FORTRAN, BASIC and C) were abstracions of assembly language. But their primary abstraction still requires you think in terms of the structure of the computer rather than the structure of the problem you are trying to solve.
The programmer must establish the association between the machine model and the model of the problem that is actually being solved, and the fact that it is extrinsic to the programming language, produces programs that are difficult to write and expensive to maintain, and as a side effect created the entire "programming methods" industry.
The alternative to modeling the machine is to model the problem you‘re trying to solve, such as "All problems are ultimately lists", or "All problems are algorithmic"; Each of these approaches may be a good solution to the particular class of problem they‘re designed to solve,but they will become awkward when you step outside of the domain.
The object-oriented approach goes a step further by providing tools for the programmer to represent elements in the problem space. This representation is general enough that the programmer is not constrained to any particular type of problem
elements in the problem space represent as objects in the solution space. (You will also need other objects that don‘t have problem-space analogs)
OOP allows you to describe the problem in terms of the problem.
Each object look quite a bit like a little computer--it has a state, and it has operations that you can ask it to perform.
Alan Kay summarized five basic characteristics of Smalltalk, the first successful objecct-oriented language and one of the languages upon which Java is based. These characteristics represent a pure approach to object-oriented programming:
1. Everythiing is an object.
2. A program is a bunch of objects telling each other what to do by sending messages.
You can think of a message as a request to call a method that belongs to a particular object.
3. Each objects has its own memory made up of other objects.
4. Every object has a type.
The most important distinguishing characteristic of a class is "What messages can you send to it?"
5. All objects of a particular type can receive the same messages.
a loaded statement 一句意义深长的表述
Substitutability is one of the powerful concepts in OOP.
An object has state, behaviore and identity.
An object has an interface(此接口应该指API,即方法)
What we really do in object-oriented programming is create new data types.
A class describes a set of objects that have identical characteristics (data elements) and behaviors (functionality).
Any program is a simulation of the system you‘re designing??What system
Indeed, one of the challenges of object-oriented programming is to create a one-to-one mapping between the elements in the program space and objects in the solution space.
Each object can satisfy only certain requests. The requested you can make of an objects are defined by its interface, and the type is what determines the interface.
An object provides services
Objects is "service providers". Your prgram itself will provide services to the user, and it will accomplish this by using the service offered by other objectes.
Your goal is to produce (or even better, locate in existing code libraries) a set of objects that provide the ideal services to solve your problem.
Thinking of an object as a service provider has an additional benefit: It helps to improve the cohesiveness of the object.
One problem people have when designing objects is cramming too much functionality into one object.
In a good object-oriented design, each object does one thing well, but doesn‘t try to do too much.
The hidden implementation
class creators and client programmers
The goal of the client programms is to collect a toolbox full of classes to user for rapid application development.
The goal of the class creator is to bulid a class that exposes only what‘s necessary to the client programmer and keep everything else hidden. Then the class creator can change the hidden portion at will without worrying about the impact on anyone else.
The reason of access control:
1. Keep client programmer‘s hands off portions they shouldn‘t touch.
2. Allow the library designer to change the internal working of the class without worrying about how it will affect the client programmer.
Java uses three explicit keywords to set the boundaries in a class: public, private, and protected.
public-- the following element is available to everyone.
private--no one can access that element except you, the creator of the type, inside methods of that type.
a brick wall between class creator and the client programmer.
protected-- acts like private, with the exception that an inheriting class has access to protected members.
"default" access-- Java also has a "default" access, which comes into play if you don‘t use one of the aforementioned specifiers.
usually called package access because classes can access the members of other classes in the same package (library component), but outside of the package those same members appear to be private
Reusing the implementation
Code reuse is one of the greatest advantages that object-oriented programming language provide.
The way to reuse a class:
1. just use an object of the class directly
2. place an object of that class inside a new class. (creating a member object)
this concept is called composition. (if the composition happens dynamically, it‘s usually called aggregation). Composition is often referred to as a "has-a" relationship.
composition 组合:表示两个对象之间是整体和部分的强关系,部分的生命周期不能超越整体,或者说不能脱离整体而存在。组合关系的“部分”,是不能在整体之间进行共享的。
aggregation 聚合:表示两个对象之间是整体和部分的弱关系,部分的生命周期可以超越整体。如电脑和鼠标。
Composition comes with a great deal of flexibility. The member objects of your new class are typically private.
1. Allows you to change those member without disturbing existing client code.
2. You can all change the member objects at run time,to dynamically changed the behavior of your program
Inheritance doesn‘t have the flexibility.
You should first look to composition when create new classes,since it is simpler and more flexible
Inheritance
Inheritance expresses this similarity between type by using the concept of base types and derived types.
You create a base type to represent the core of your ideas about some objects in your system. From the base type, you derive other types of express the different ways that this core can be realized.
Casting the solution in the same terms as the problem is very useful,not need a lot of intermediated models
The type equivalence via inheritance is one of the fundamental gateways in understanding the meaning of object-oriented programming.
The way to differentiate your new derived class from the original base class:
1. Simply add brand new methods to the derived class.
2. Change the behavior of an existing base-class method. (overriding)
Is-a vs. is-like-a relationships
A test for inheritance is to determine whether you can state the is-a relationship about the class and have it make sense.
Is-a: inheritance override only base class methods. (pure substitution)
Is-like-a: add new methods to a derived type
Interchangeable objects with polymorphism
type hierarchies 类型分级结构
When dealing with type hierarchies, you often want to treat an object not as the specific type that it is, but instead as its base type.
early binding 前期绑定
In OOP, the program cannot determine the address of the code until run time, so some other scheme is necessary when a message is sent to a generic object.
To solve the program, object-oriented languages use the concept of late binding.
early binding:the compiler generates a call to a specific function name, and the runtim system resolves this call to the absolute address of the code to be executed.
late binding: Java use a special bit of code in lieu of the absolute call. This code calculates the address of the method body, using information stored in the object. (dynamic binding)
In Java,dynamic binding is the default behaviore and you don‘t need to remember to add any extra keywords (C++ uses virtual keyword) in order to get polymorphism.
upcasting(向上转型)-- the process of treating a derived type as though it were its base type
The name "cast" is used in the sense of casting into a mold
The "up" comes from the way the inheritance diagram is typically arranged, with the base type at the top and the derived classes fanning out downward.
The singly rooted hierarchy (单根继承结构)
In Java, all classed are ultimately inherited from a single base class, and the name of this ultimate base class is simply Object.
Containers (Collection)
In Java, the library has different types of containers for different needs: List (to hold sequences), Map (to associate objects with other objects), Set (to hold one of each type of object ), and more components such as queues, trees, stacks, etc.
There are two reasons that you need a choice of containers:
1. containers provide different types of interfaces and external behavior.
2. different containers have different efficiencies for certain operations.
Parameterized types (generics)
Befor Java SE5, containers held the one universal type in Java: Object. The singly rooted hierarchy means that everything is an Object, so a container that hold Object can hold anything. But, sine the container held only Objects, when you added an object reference into the
container it was upcast to Object, thus losing its character. So you need downcasting, but it‘s not safe. It‘s not completely dangerous, however, because if you downcast to the wrong thing you‘ll get a runtime error called an exception.
Downcasting and the runtime checks require extra time for the running program and extra effort from the programmer.
The solution is called a parameterized type mechanism. (Java SE5,called generics)
A parameterized type (编译器层次的技术) is a class that the compiler can automatically customize to work with particular types.
Object creation & lifetime
When to destroy object?
C++ takes the approach that control of efficiency is the most important issue, so it gives the programmers a choice.
Java uses dynamic memory allocation
Garbage collector
With Java, the garbage collector is designed to take care of the problem of releasing the memory (although this does‘t include other aspects of cleaning up an object).
Exception handling: dealing with errors
expection handling isn‘t an object-oriented feature.
Concurrent programming
There is a catch in Concurrency: shared resources.
To solve the problem: task locks a resource, completes its task, and then releases the lock.
Java and the Internet