版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> The progress of Abstraction</p><p> All programming languages provide abstractions. It can be argued that the complexity of the problems you’re able to solve is directly related to the kind and q
2、uality of abstraction. By “kind” I mean, “What is it that you are abstracting?” Assembly language is a small abstraction of the underlying machine. Many so-called “imperative” languages that followed (such as Fortran, BA
3、SIC, and C) were abstractions of assembly language.These languages are big improvements over assembly language, but their</p><p> PROLOG casts all problems into chains of decisions. Languages have been crea
4、ted for constraint-basedprogramming and for programming exclusively by manipulating graphical symbols. (The latter proved to be too restrictive.) Each of these</p><p> approaches is a good solution to the p
5、articular class of problem they’re designed to solve, but when you step outside of that domain they become awkward. The object-oriented approach goes a step further by providing tools for</p><p> the progra
6、mmer to represent elements in the problem space.Thisrepresentation is general enough that the programmer is not constrained to any particular type of problem. We refer to the elements in the problem space and their repre
7、sentations in the solution space as “objects.” (Of course, you will also need other objects that don’t have problem-space</p><p> analogs.) The idea is that the program is allowed to adapt itself to the lin
8、go of the problem by adding new types of objects, so when you read the code describing the solution, you’re reading words that also express the problem. This is a more flexible and powerful language abstraction than what
9、 we’ve had before. Thus, OOP allows you to describe the problem in terms of the problem, rather than in terms of the computer where the solution will run. There’s still a connection back to the computer, </p><
10、p> Each object looks quite a bit like a little computer; it has a state, and it has operations that you can ask it to perform. However, this doesn’t seem like such a bad analogy to objects in the real world—they all
11、have characteristics and behaviors. Some language designers have decided that object-oriented programming by itself is not adequate to easily solve all programming problems, and advocate the combination of various approa
12、ches into multiparadigm programming languages.</p><p> Alan Kay summarized five basic characteristics of Smalltalk, the first</p><p> successful object-oriented language and one of the languag
13、es upon which</p><p> Java is based. These characteristics represent a pure approach to objectoriented</p><p> programming:</p><p> 1. Everything is an object. Think of an object
14、 as a fancy variable; it stores data, but you can “make requests” to that object, asking it to perform operations on itself. In theory, you can take any conceptual component in the problem you’re trying to solve</p>
15、;<p> (dogs, buildings, services, etc.) and represent it as an object in your program.</p><p> 2. A program is a bunch of objects telling each other what to do by sending messages. To make a request
16、 of an object, you “send a message” to that object. More concretely, you can think of a message as a request to call a function that belongs to a particular object.</p><p> 3. Each object has its own memory
17、 made up of other objects. Put another way, you create a new kind of object by making a package containing existing objects. Thus, you can build complexity in a program while hiding it behind the simplicity of objects.&l
18、t;/p><p> 4. Every object has a type. Using the parlance, each object is an instance of a class, in which “class” is synonymous with “type.” The most important distinguishing characteristic of a class is “What
19、 messages can you send to it?”</p><p> 5. All objects of a particular type can receive the same messages. This is actually a loaded statement, as you will see later. Because an object of type “circle” is al
20、so an object of type “shape,” a circle is guaranteed to accept shape messages. This means you can write code that talks to shapes and automatically handle anything that fits the description of a shape. This substitutabil
21、ity is one of the most powerful concepts in OOP.</p><p> An object has an interface</p><p> Aristotle was probably the first to begin a careful study of the concept of type; he spoke of “the c
22、lass of fishes and the class of birds.” The idea that all objects, while being unique, are also part of a class of objects that have characteristics and behaviors in common was used directly in the first object-oriented
23、language, Simula-67, with its fundamental keyword class that introduces a new type into a program. Simula, as its name implies, was created for developing simulations such as the c</p><p> program. This ent
24、ity is the object, and each object belongs to a particular class that defines its characteristics and behaviors. So, although what we really do in object-oriented programming is create new data types, virtually all objec
25、t-oriented programming languages use the “class” keyword. When you see the word “type” think “class” and vice versa2. Since a class describes a set of objects that have identical characteristics (data elements) and behav
26、iors (functionality), a class is really a d</p><p> because a floating point number, for example, also has a set of characteristics and behaviors. The difference is that a programmer defines a class to fit
27、 a problem rather than being forced to use an existing data type that was designed to represent a unit of storage in a machine. You extend the programming language by adding new data types specific to your needs. The pro
28、gramming system welcomes the new classes and gives them all the care and type-checking that it gives to built-in types. The ob</p><p> of problems to a simple solution. Once a class is established, you can
29、make as many objects of that class as you like, and then manipulate those objects as if they are the elements that exist in the problem you are trying to solve. Indeed, one of the</p><p> challenges of obje
30、ct-oriented programming is to create a one-to-one mapping between the elements in the problem space and objects in the solution space.But how do you get an object to do useful work for you? There must be a way to make a
31、request of the object so that it will do something, such as complete a transaction, draw something on the screen, or turn on a switch. And each object can satisfy only certain requests. The requests you</p><p&
32、gt; can make of an object are defined by its interface, and the type is what determines the interface. A simple example might be a representation of a light bulb:The interface establishes what requests you can make for
33、a particular object. However, there must be code somewhere to satisfy that request.This, along with the hidden data, comprises the implementation. From a procedural programming standpoint, it’s not that complicated. A ty
34、pe has a function associated with each possible request, and when</p><p> create a Light object by defining a “reference” (lt) for that object and calling new to request a new object of that type. To send a
35、 message to the object, you state the name of the object and connect it to the message request with a period (dot). From the standpoint of the user of a predefined class, that’s pretty much all there is to programming wi
36、th</p><p> objects. The diagram shown above follows the format of the Unified Modeling Language (UML). Each class is represented by a box, with the type name in the top portion of the box, any data members
37、that you care to describe in the middle portion of the box, and the member functions (the functions that belong to this object, which receive any messages you send to that object) in the bottom portion of the box. Often,
38、 only the name of the class and the public member functions are shown in UML design d</p><p> The hiddenimplementation</p><p> It is helpful to break up the playing field into class creators (
39、those who create new data types) and client programmers3 (the class consumers who use the data types in their applications). The goal of the client programmer is to collect a toolbox full of classes to use for rapid appl
40、ication development. The goal of the class creator is to build a class</p><p> that exposes only what’s necessary to the client programmer and keeps everything else hidden. Why? Because if it’s hidden, the
41、client programmer can’t use it, which means that the class creator can change the hidden portion at will without worrying about the impact to anyone else. The hidden portion usually represents the tender insides of an ob
42、ject that could easily be corrupted by a careless or uninformed client programmer, so hiding the implementation reduces program bugs. The concept of impl</p><p> can ignore. The second reason for access con
43、trol is to allow the library designer to</p><p> change the internal workings of the class without worrying about how itwill affect the client programmer. For example, you might implement a particular class
44、 in a simple fashion to ease development, and then later discover that you need to rewrite it in order to make it run faster. If the interface and implementation are clearly separated and protected, you can accomplish th
45、is easily. </p><p> Java uses three explicit keywords to set the boundaries in a class: public,private, and protected. Their use and meaning are quite straightforward. These access specifiers determine who
46、can use the definitions that follow. public means the following definitions are available to everyone. The private keyword, on the other hand, means that no one can access those definitions except you, the creator of the
47、 type, inside member functions of that type. private is a brick wall between you and the clien</p><p> private, with the exception that an inheriting class has access to protected members, but not private m
48、embers. Inheritance will be introduced shortly.</p><p><b> 抽象過程</b></p><p> 所有編程語言都提供抽象(abstraction)機制??梢哉J為,你所能夠解決的問題的復雜性直接取決于抽象的類型和質量。我所謂的"類型"是指"你所抽象的是什么?"匯編語言
49、是對底層機器的小型抽象。接著出現(xiàn)的許多所謂"命令式(Imperative)"語言(諸如 FORTRAN、BASIC、C 等)都是對匯編語言的抽象。這些語言在匯編語言之上有了大幅的改進,但是它們所作的主要抽象仍要求你在解決問題時要基于計算機的結構,而不是基于你試圖要解決的問題的結構來考量。程序員必須建立在機器模型(Machine Model)(位于你對問題建模所在的解空間 (Solution Space)內,例如計算機
50、)和實際待解問題模型(Problem Model)(位于問題所在的問題空間(Problem Space)內)之間的關聯(lián)。建立這種映射(Mapping)是費力的,而且它不屬于編程語言的內在性質,這使得程序難以編寫,并且維護代價高昂。由此,產生了完整的"編程方法(Programming Method)"產業(yè)。 </p><p> 另一種對機器建模的方式就是對待解決問題建模。早期的編程語言,諸如
51、LISP 和 APL 都選擇世界的某種特定視圖(分別對應于"所有問題最終都是列表(List)"或者"所有問題都是算法形式的(algorithmic)")。PROLOG 則將所有問題都轉換成為決策鏈(Chain of decisions)。此外還產生了基于約束條件(constraint-based)編程的語言和專門通過對圖形符號操作來實現(xiàn)編程的語言(后者被證明限制性過強)。這些方式對于它們被設計時所
52、瞄準要解決的特定類型的問題都是不錯的解決方案,但是一旦超出其特定領域,它們就力不從心了。</p><p> 面向對象方式(Object-oriented approach)通過向程序員提供用來表示在問題空間中的元素 的工具而更進一步。這種表示方式具有足夠的概括性,使得程序員不會受限于任何特定類型的問題。我們將問題空間中的元素及其在解空間中的表示成為"對象(Object)"。(你還需要一些無
53、法類比為問題空間元素的對象)。這種思想的實質是:程序可以通過添加新類型的對象使自身適用于某個特定問題。因此,當你在閱讀描述解決方案的代碼的同時,也是在閱讀問題的表述。相比以前我們所擁有的所有語言,這是一種更靈活和更強有力的語言抽象。所以,OOP允許以問題的形式來描述問題,而不是以執(zhí)行解決方案的計算機的形式來描述問題。但是它仍然與計算機有聯(lián)系:每個對象看起來都有點像一臺微型計算機——它具有狀態(tài),并且能夠執(zhí)行你賦予它的各種操作。如果要在現(xiàn)實
54、世界中對對象作類比,那么說它們都具有特性(Characteristic)和行為(Behavior)似乎不錯。 </p><p> Alan Kay 曾經總結了第一個成功的面向對象語言,同時也是 Java 賴為根基的語言之一的 Smalltalk 的五個基本特性,這些特性表現(xiàn)了一種純粹的面向對象程序設計方式: </p><p> 1萬物皆為對象。將對象視為奇特的變量,它可以存儲數(shù)
55、據(jù),除此之外,你還可以要求它在自身上執(zhí)行操作。理論上講,你可以抽取待解問題的任何概念化構件(狗、建筑物、服務等),將其表示為程序中的對象。 </p><p> 2程序是對象的集合,它們彼此通過發(fā)送消息來調用對方。要想產生一個對對象的請求,就必須對該對象發(fā)送一條消息。更具體地說,你可以把消息想象為對某個特定對象的方法的調用請求。 </p><p> 3每個對象都擁有由其它對象所構成的存儲
56、。你可以通過創(chuàng)建包含現(xiàn)有對象集合的包的方式來創(chuàng)建新類型的對象。因此,你可以在程序中構建復雜的體系,同時將其復雜性通過對象的質樸性得以屏蔽。 </p><p> 4每個對象都擁有其類型(Type)。按照通用的說法,"每個對象都是某個類(Class)的一個實例(Instance)",其中"類"就是"類型"的同義詞。每個類中最重要的區(qū)別于其它類的特性就是&q
57、uot;你可以發(fā)送什么消息給它?" </p><p> 5某一特定類型的所有對象都可以接收(Receive)同樣的消息。這是一句意味深長的表述,你在稍后便會看到。因為"圓形(circle)"類型的對象同時也是"幾何形(shape)"類型的對象,所以一個"圓形"對象必定能夠接受(accept)發(fā)送給"幾何形"對象的消息。這意
58、味著你可以編寫與"幾何形"交互并自動處理所有與幾何形性質相關的事物的的代碼。 </p><p> 這種"可替代性(substitutability)"是 OOP 中最強有力的概念之一。Booch 提出了一個對對象的更加簡潔的描述:對象擁有狀態(tài)(State)、行為(Behaviour)和標 </p><p> 識(Identity)。這意味著每一
59、個對象都可以擁有內部數(shù)據(jù)(它們給出了該對象的狀態(tài))和方法(它們產生行為),并且每一個對象都可以唯一地與其他對象相區(qū)分開,具體說來,就是每一個對象在內存中都有一個唯一的地址。</p><p> 每個對象都有一個接口 </p><p> 亞里士多德大概是第一個深入研究類型(Type)的哲學家,他曾提出過魚類和鳥類(the class of fishes and the class of b
60、irds)這樣的概念。所有的對象都是唯一的,但同時也是具有相同的特性和行為的對象所歸屬的類的一部分,這種思想被直接應用于第一個面向對象語言Simula-67,它在程序中使用基本關鍵詞 class 來引入新的類型。Simula,就像其名字一樣,是為了開發(fā)諸如經典的"銀行出納員問題(Bank teller problem)" 這樣的仿真程序而創(chuàng)建的。在銀行出納員問題中,有出納員、客戶、賬戶、交易和貨幣單位等許多"
61、;對象"。在程序執(zhí)行期間具有不同的狀態(tài)而其他方面都相似的對象會被分組到對象的類中,這就是關鍵詞 class 的由來。創(chuàng)建抽象數(shù)據(jù)類型(類)是面向對象程序設計的基本概念之一。抽象數(shù)據(jù)類型的運行方式與內置(built-in)類型幾乎完全一致:你可以創(chuàng)建某一類型的變量(按照面向對象的說法,程其為對象或實例),然后操作這些變量(稱其為發(fā)送消息或請求;你發(fā)送消息,對象就能夠知道需要做什么)。每個類的成員(member)或元素(eleme
62、nt)</p><p> 稱。因此,出納、客戶、賬戶、交易等都可以在計算機程序中被表示成為唯一的實體(entity)這些實體就是對象,每一個對象都屬于定義了特性和行為的某個特定的類。所以,盡管我們在面向對象程序設計中實際所作的是創(chuàng)建新的數(shù)據(jù)類型,但事實上所有的面向對象程序設計語言都使用Class關鍵詞來表示數(shù)據(jù)類型。當你看到類型(Type)一詞時,請將其作為類(Class)來考慮,反之亦然。 </p>
63、;<p> 既然類被描述成了具有相同特性(數(shù)據(jù)元素)和行為(功能)的對象集合,那么一個類就確實是一個數(shù)據(jù)類型,就像所有浮點型數(shù)字具有相同的特性和行為集合一樣。二者的差異在于,程序員通過定義類來適應問題,而不再被強制只能使用現(xiàn)有的被設計用來表示在機器中的存儲單元的數(shù)據(jù)類型。你可以根據(jù)需求,通過添加新的數(shù)據(jù)類型來擴展編程語言。編程系統(tǒng)欣然接受新的類,并且給予它們與內置類型相同的管護和類型檢查(Type-checking)。面
64、向對象方法并不是僅局限于構件仿真程序。無論你是否同意任何程序都是你所設計的系統(tǒng)的一個仿真的觀念,面向對象技術確實可以將大量的問題降解為一個簡單的解決方案。一旦類被建立,你想要創(chuàng)建該類的多少個對象,就可以創(chuàng)建多少個了,然后去操作它們,就像它們是存在于你的待解問題中的元素一樣。事實上,面向對象程序設計的挑戰(zhàn)之一,就是在問題空間的元素和解空間的對象之間創(chuàng)建一對一的映射。但是,你怎樣才能獲得對你有用的對象呢?必須有某種方式產生對對象的請求,使對
65、象完成諸如完成一筆交易、在屏幕上畫圖、打開開關之類的任務。每個對象都只能滿足某些請求,這些請求由對象的接口(Interface)所定義,決定接口的便</p><p> 做一個簡單的比喻:Light lt = new Light(); lt.on(); 接口定義了你能夠對某一特定對象發(fā)出的請求。但是,在程序中必須有滿足這些請求的代碼。這些代碼與隱藏的數(shù)據(jù)一起構成了實現(xiàn)(implementation)。從過程型編程
66、的觀點來看,這并不太復雜。在類型中,每一個可能的請求都有一個方法與之相關聯(lián),當你向對象發(fā)送請求時,與之相關聯(lián)的方法就會被調用。此過程通常被總結為:你向某個對象發(fā)送消息(產生請求),這個對象便知道此消息的目的,然后執(zhí)行對應的程序代碼。 </p><p> 上例中,類型/類的名稱是 Light,特定的 Light 對象的名稱是 lt,你可以向 Light 對象發(fā)出的請求是:打開它、關閉它、將它調亮、將它調暗。你以這
67、種方式創(chuàng)建了一個 Light 對象:定義這個對象的"引用(reference)"(lt),然后調用 new 方法來創(chuàng)建該類型的新對象。為了向對象發(fā)送消息,你需要聲明對象的名稱,并以圓點符號連接一個消息請求。從預定義類的用戶觀點來看,這些差不多就是用對象來進行設計的全部。 </p><p> 前面的圖是 UML(Unified Modelling Language)形式的圖,每個類都用一個方框
68、表示,類名在方框的頂部,你所關心的任何數(shù)據(jù)成員(data member)都描述在方框的中間部分,方法(隸屬于此對象的,用來接收你發(fā)給此對象的消息的函數(shù))在方框的底部。通常,只有類名和公共方法(Public Method)被示于 UML 設計圖中,因此,方框的中部并不繪出。如果你只對類型感興趣,那么方框的底部甚至也不需要被繪出。 </p><p> 每個對象都提供服務 </p><p>
69、 當你正是如開發(fā)或理解一個程序設計時,最好的方法之一就是將對象想象為"服務提供者(Service Provider)"。你的程序本身將向用戶提供服務,它將通過調用其它對象提供的服務來實現(xiàn)這一目的。你的目標就是去創(chuàng)建(或者最好是在現(xiàn)有代碼庫中尋找)能夠提供理想的服務來解決問題的對象集合。著手從事這件事的方式之一是詢問"如果我可以將問題從表象中抽取出來,那么什么樣的對 象可以馬上解決我的問題呢?"例如
70、,假設你正在創(chuàng)建一個簿記(Bookkeeping)系統(tǒng),你可以想象系統(tǒng)應該具有某些包括了預定義的簿記輸入屏幕的對象,一個執(zhí)行簿記計算的對象集合,以及一個處理在不同的打印機上打印支票和開發(fā)票的對象。也許上述對象中的某些已經存在了,但是對于那些并不存在的對象,它們看起來什么樣?它們能夠提供哪些服務?它們需要哪些對象才能履行它們的義務?如果你持續(xù)這樣做,你最終會發(fā)現(xiàn)你將到達這樣一個節(jié)點:你會說"那個對象看起來很簡單,以至可以坐下來寫
71、代碼了",或者會說"我肯定那個對象已經存在了"。這是將問題分解為對象集合的一種合理方式。將對象看作是服務提供者還有一個附加的好處:它有助于提高對象的內聚性(cohesive</p><p> 對象集合可以是一個通用的打印接口,它知道有關所有不同類型的打印機的信息(但是不包含任何有關簿記的內容,它更應該是一個需要購買而不是自己編寫的對象);第三個對象通過調用另外兩個對象的服務來完成打
72、印任務。因此,每個對象都有一個它所能提供服務的高內聚的集合。在良好的面向對象設計中,每個對象都可以很好地完成一項任務,但是它并不試圖多更多的事。就像在這里看到的,不僅允許某些對象可以通過購買獲得(打印機接口對象),而且還使對象在某處重用成為可能(支票排版目錄對象)。將對象作為服務提供者看待是一件偉大的簡化工具,它不僅在設計過程中非常有用,而且當其他人試圖理解你的代碼或重用某個對象時(如果他們看出了這個對象所能提供的服務的價值所在的話),
73、它會使將對象調整到適應其設計的過程變得簡單得多。</p><p><b> 被隱藏的具體實現(xiàn) </b></p><p> 將程序開發(fā)人員按照角色分為類創(chuàng)建者(class creator,那些創(chuàng)建新數(shù)據(jù)類型的程序員)和客戶端程序員 (client programmer,那些在其應用中使用數(shù)據(jù)類型的類消費者)是大有裨益的??蛻舳顺绦騿T的目標是收集各種用來實現(xiàn)快速應用開
74、發(fā)(Rapid Application Development)的類。類創(chuàng)建者的目標是構建類,該類只向客戶端程序員暴露必需的部分,而隱藏其它所有部分。為什么要這樣呢?因為如果加以隱藏,那么客戶端程序員將不能夠訪問它,這意味著類 創(chuàng)建者可以任意修改被隱藏的部分,而不用擔心對其他任何人造成影響。被隱藏的部分通常代表對象內部脆弱的部分,它們很容易被粗心的或不知內情的客戶端程序員所毀壞,因此將實現(xiàn)隱藏起來可以減少程序的Bug。實現(xiàn)隱藏的概念再怎
75、么強調也不會過分。在任何相互關系中,具有關系所涉及的各方都遵守的邊界是十分重要的事情。當你創(chuàng)建一個類庫(Library)時,你就建立了與客戶端程序員之間的關系,他們同樣也是程序員,但是他們是使用你的類庫來構建應用,或者是構建更大的類庫的程序員。如果所有的類成員(Member)對任何人都是可用的,那么客戶端程序員就可</p><p> 因此,訪問控制的第一個存在原因就是讓客戶端程序員無法觸及他們不應該觸及的部分—
76、—這些部分對數(shù)據(jù)類型的內部操作來說是必需的,但并不是用戶需要的用來解決特定問題的接口的一部分。這對用戶來說其實是一項服務,因為他們可以很容易地看出哪些東西對他們來說很重要,而哪些東西可以忽略。 </p><p> 訪問控制的第二個存在原因就是允許庫設計者可以改變類內部的工作方式而不用擔心是否會影響到客戶端程序員。例如,你可能為了減輕開發(fā)任務而以某種簡單的方式實現(xiàn)了某個特定類,但稍后你就發(fā)現(xiàn)你必須改寫它才能使其運
77、行得更快。如果接口和實現(xiàn)可以清晰地分離并得以保護,那么你就可以輕而易舉地完成這項工作。 </p><p> Java 使用三個關鍵字來在類的內部設定邊界:public、private、protected。它們的含義和用法非常易懂。這些"訪問指定詞(access specifier)"決定了緊跟其后被定義的東西可以被誰使用。public 表示緊隨其后的元素對任何人都是可用的,另一方面,priv
78、ate 這個關鍵字表示除類型創(chuàng)建者和該類型的內部方法之外的任何人都不能訪問的元素。private 就像你與客戶端程序員之間的一堵磚墻,如果有人試圖訪問 private 成員,就會在編譯時刻得到錯誤信息。protected 關鍵字與 private 作用相當,差別僅在于繼承類(Inheriting class)可以訪問 protected 成員,但是不能訪問 private 成員。稍后將會對繼承(Inheritance)進行介紹。 &
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 外文翻譯---軟件過程模型
- 外文翻譯---軟件和軟件工程
- 外文翻譯---軟件和軟件工程
- 外文翻譯-軟件工程
- 軟件開發(fā)外文翻譯
- 外文翻譯---軟件測試策略
- 計算機外文翻譯--java抽象窗口工具包
- 軟件編程設計-外文翻譯
- 軟件開發(fā)外文翻譯(節(jié)選)
- 軟件工程專業(yè)外文翻譯
- 金屬鑄造過程外文翻譯
- 評估軟件即服務【外文翻譯】
- 軟件外包的發(fā)展【外文翻譯】
- eda技術及軟件外文翻譯
- 外文翻譯---java學習過程
- 機械設計過程外文文獻翻譯@中英翻譯@外文翻譯
- 計算機畢業(yè)設計外文翻譯--現(xiàn)代并發(fā)抽象c#
- 機械專業(yè)外文翻譯calypso軟件說明
- 戰(zhàn)略管理過程【外文翻譯】
- 外文翻譯--鑄造和鑄造過程
評論
0/150
提交評論