『壹』 怎麼學習編程
學編程會有以下逐步學習的過程:
1.熟練掌握java Web程序開發
2.熟練掌握MVC框架的企業級開發
3.熟練掌握資料庫面向對象的開發
4.Linux系統原理、常用命令、Shell腳本編程/Unix系統原理
5.熟練掌握軟體大型化,切面化,多視圖技術。
6.企業級軟體標准化作業流程
建議樓主找一家好的電腦培訓學校學習,這樣才可能比較好的學到你想學的知識。我覺得新華電腦不錯,我在裡面進行過短期培訓。我認為學校最好的地方在於都是從基礎開始授課,這樣也不用擔心自己基礎不好而跟不上了。你可以去了解下,希望能幫到你。
持續學習,持續開發,是目前主流IT業界程序員的一個生活常規,在現代技術迭代速度非常快的情況下,只有不斷保持自我學習和探索才不會與時代脫節。無論是專業的IT從業者還是IT小白,都需要培養自己的演算法思維。昆明電腦培訓http://www.kmbdqn.cn/發現擁有良好演算法思維後的直接好處有:更高的面試成功機會,和更快的日常問題處理能力。
何為演算法思維,並不是對一些已經設計好的優秀代碼的反復背誦和背板,而是自己對於問題的抽象能力的練習,即從抽象問題到實際進行編碼或者設計程序解決問題的一個能力,如果單純對於一些演算法進行背誦的話,我們的思維能力不會得到提升,最多就是熟練的碼農而已。所以,當看到別人設計的優秀演算法後,我們一定要探尋演算法背後那「曲徑通幽」的思維之路。只有經歷了思維之路的磨難,才能永遠佔有一個演算法,並有可能舉一反三,或者是設計一個巧妙演算法。
個人認為,對於提升演算法思維的方法,首先我們需要深入思考各種苦惱的問題,例如:
假設我喜歡租車出行,那麼對於某一個地方的停車點一般在什麼時候有車的機率最大?有車的概率是否與天氣,溫度等因素有關?
我希望可以在回家之前通過手機APP讓家裡的空調提前工作起來,但是我非常Geek,不想使用現成的產品而想自己實現一個,和同學吹牛的時候可以更加脫穎而出?
在明確了這些問題以後我們就可以開始思考如何嘗試寫一個小的程序來幫助自己解決,這個時候如果手頭有一個習慣的語言就非常合適了(比如我個人就喜歡Python,有很多庫可以使用,而且入門非常容易),如果沒有的話,可以去看看各個語言合適的場景,不過對於爬蟲、數據分析相關個人認為更加貼合日常生活的項目來看,還是考慮直接從Python3起步比較好,後期如果想用樹莓派做點智能家居相關的項目的話Python也是非常合適的。
對於Python的學習,目前有很多非常成熟的課程,可以覆蓋各個不同的能力范圍,這里著重推薦Coursera的視頻課程,配合本地IPython或者LeetCodePlayground一起調試和練習,可以獲得很好的效果。
『叄』 高手大哥們,如何提高編程思想
第1章 對象入門
「為什麼面向對象的編程會在軟體開發領域造成如此震憾的影響?」
面向對象編程(OOP)具有多方面的吸引力。對管理人員,它實現了更快和更廉價的開發與維護過程。對分析與設計人員,建模處理變得更加簡單,能生成清晰、易於維護的設計方案。對程序員,對象模型顯得如此高雅和淺顯。此外,面向對象工具以及庫的巨大威力使編程成為一項更使人愉悅的任務。每個人都可從中獲益,至少表面如此。
如果說它有缺點,那就是掌握它需付出的代價。思考對象的時候,需要採用形象思維,而不是程序化的思維。與程序化設計相比,對象的設計過程更具挑戰性——特別是在嘗試創建可重復使用(可再生)的對象時。過去,那些初涉面向對象編程領域的人都必須進行一項令人痛苦的選擇:
(1) 選擇一種諸如Smalltalk的語言,「出師」前必須掌握一個巨型的庫。
(2) 選擇幾乎根本沒有庫的C++(注釋①),然後深入學習這種語言,直至能自行編寫對象庫。
①:幸運的是,這一情況已有明顯改觀。現在有第三方庫以及標準的C++庫供選用。
事實上,很難很好地設計出對象——從而很難設計好任何東西。因此,只有數量相當少的「專家」能設計出最好的對象,然後讓其他人享用。對於成功的OOP語言,它們不僅集成了這種語言的語法以及一個編譯程序(編譯器),而且還有一個成功的開發環境,其中包含設計優良、易於使用的庫。所以,大多數程序員的首要任務就是用現有的對象解決自己的應用問題。本章的目標就是向大家揭示出面向對象編程的概念,並證明它有多麼簡單。
本章將向大家解釋Java的多項設計思想,並從概念上解釋面向對象的程序設計。但要注意在閱讀完本章後,並不能立即編寫出全功能的Java程序。所有詳細的說明和示例會在本書的其他章節慢慢道來。
1.1 抽象的進步
所有編程語言的最終目的都是提供一種「抽象」方法。一種較有爭議的說法是:解決問題的復雜程度直接取決於抽象的種類及質量。這兒的「種類」是指准備對什麼進行「抽象」?匯編語言是對基礎機器的少量抽象。後來的許多「命令式」語言(如FORTRAN,BASIC和C)是對匯編語言的一種抽象。與匯編語言相比,這些語言已有了長足的進步,但它們的抽象原理依然要求我們著重考慮計算機的結構,而非考慮問題本身的結構。在機器模型(位於「方案空間」)與實際解決的問題模型(位於「問題空間」)之間,程序員必須建立起一種聯系。這個過程要求人們付出較大的精力,而且由於它脫離了編程語言本身的范圍,造成程序代碼很難編寫,而且要花較大的代價進行維護。由此造成的副作用便是一門完善的「編程方法」學科。
為機器建模的另一個方法是為要解決的問題製作模型。對一些早期語言來說,如LISP和APL,它們的做法是「從不同的角度觀察世界」——「所有問題都歸納為列表」或「所有問題都歸納為演算法」。PROLOG則將所有問題都歸納為決策鏈。對於這些語言,我們認為它們一部分是面向基於「強制」的編程,另一部分則是專為處理圖形符號設計的。每種方法都有自己特殊的用途,適合解決某一類的問題。但只要超出了它們力所能及的范圍,就會顯得非常笨拙。
面向對象的程序設計在此基礎上則跨出了一大步,程序員可利用一些工具表達問題空間內的元素。由於這種表達非常普遍,所以不必受限於特定類型的問題。我們將問題空間中的元素以及它們在方案空間的表示物稱作「對象」(Object)。當然,還有一些在問題空間沒有對應體的其他對象。通過添加新的對象類型,程序可進行靈活的調整,以便與特定的問題配合。所以在閱讀方案的描述代碼時,會讀到對問題進行表達的話語。與我們以前見過的相比,這無疑是一種更加靈活、更加強大的語言抽象方法。總之,OOP允許我們根據問題來描述問題,而不是根據方案。然而,仍有一個聯系途徑回到計算機。每個對象都類似一台小計算機;它們有自己的狀態,而且可要求它們進行特定的操作。與現實世界的「對象」或者「物體」相比,編程「對象」與它們也存在共通的地方:它們都有自己的特徵和行為。
Alan Kay總結了Smalltalk的五大基本特徵。這是第一種成功的面向對象程序設計語言,也是Java的基礎語言。通過這些特徵,我們可理解「純粹」的面向對象程序設計方法是什麼樣的:
(1) 所有東西都是對象。可將對象想像成一種新型變數;它保存著數據,但可要求它對自身進行操作。理論上講,可從要解決的問題身上提出所有概念性的組件,然後在程序中將其表達為一個對象。
(2) 程序是一大堆對象的組合;通過消息傳遞,各對象知道自己該做些什麼。為了向對象發出請求,需向那個對象「發送一條消息」。更具體地講,可將消息想像為一個調用請求,它調用的是從屬於目標對象的一個子常式或函數。
(3) 每個對象都有自己的存儲空間,可容納其他對象。或者說,通過封裝現有對象,可製作出新型對象。所以,盡管對象的概念非常簡單,但在程序中卻可達到任意高的復雜程度。
(4) 每個對象都有一種類型。根據語法,每個對象都是某個「類」的一個「實例」。其中,「類」(Class)是「類型」(Type)的同義詞。一個類最重要的特徵就是「能將什麼消息發給它?」。
(5) 同一類所有對象都能接收相同的消息。這實際是別有含義的一種說法,大家不久便能理解。由於類型為「圓」(Circle)的一個對象也屬於類型為「形狀」(Shape)的一個對象,所以一個圓完全能接收形狀消息。這意味著可讓程序代碼統一指揮「形狀」,令其自動控制所有符合「形狀」描述的對象,其中自然包括「圓」。這一特性稱為對象的「可替換性」,是OOP最重要的概念之一。
一些語言設計者認為面向對象的程序設計本身並不足以方便解決所有形式的程序問題,提倡將不同的方法組合成「多形程序設計語言」(注釋②)。
②:參見Timothy Budd編著的《Multiparadigm Programming in Leda》,Addison-Wesley 1995年出版。
1.2 對象的介面
亞里士多德或許是認真研究「類型」概念的第一人,他曾談及「魚類和鳥類」的問題。在世界首例面向對象語言Simula-67中,第一次用到了這樣的一個概念:
所有對象——盡管各有特色——都屬於某一系列對象的一部分,這些對象具有通用的特徵和行為。在Simula-67中,首次用到了class這個關鍵字,它為程序引入了一個全新的類型(clas和type通常可互換使用;注釋③)。
③:有些人進行了進一步的區分,他們強調「類型」決定了介面,而「類」是那個介面的一種特殊實現方式。
Simula是一個很好的例子。正如這個名字所暗示的,它的作用是「模擬」(Simulate)象「銀行出納員」這樣的經典問題。在這個例子里,我們有一系列出納員、客戶、帳號以及交易等。每類成員(元素)都具有一些通用的特徵:每個帳號都有一定的余額;每名出納都能接收客戶的存款;等等。與此同時,每個成員都有自己的狀態;每個帳號都有不同的余額;每名出納都有一個名字。所以在計算機程序中,能用獨一無二的實體分別表示出納員、客戶、帳號以及交易。這個實體便是「對象」,而且每個對象都隸屬一個特定的「類」,那個類具有自己的通用特徵與行為。
因此,在面向對象的程序設計中,盡管我們真正要做的是新建各種各樣的數據「類型」(Type),但幾乎所有面向對象的程序設計語言都採用了「class」關鍵字。當您看到「type」這個字的時候,請同時想到「class」;反之亦然。
建好一個類後,可根據情況生成許多對象。隨後,可將那些對象作為要解決問題中存在的元素進行處理。事實上,當我們進行面向對象的程序設計時,面臨的最大一項挑戰性就是:如何在「問題空間」(問題實際存在的地方)的元素與「方案空間」(對實際問題進行建模的地方,如計算機)的元素之間建立理想的「一對一」對應或映射關系。
如何利用對象完成真正有用的工作呢?必須有一種辦法能向對象發出請求,令其做一些實際的事情,比如完成一次交易、在屏幕上畫一些東西或者打開一個開關等等。每個對象僅能接受特定的請求。我們向對象發出的請求是通過它的「介面」(Interface)定義的,對象的「類型」或「類」則規定了它的介面形式。「類型」與「介面」的等價或對應關系是面向對象程序設計的基礎。
下面讓我們以電燈泡為例:
Light lt = new Light();
lt.on();
在這個例子中,類型/類的名稱是Light,可向Light對象發出的請求包括包括打開(on)、關閉(off)、變得更明亮(brighten)或者變得更暗淡(dim)。通過簡單地聲明一個名字(lt),我們為Light對象創建了一個「句柄」。然後用new關鍵字新建類型為Light的一個對象。再用等號將其賦給句柄。為了向對象發送一條消息,我們列出句柄名(lt),再用一個句點符號(.)把它同消息名稱(on)連接起來。從中可以看出,使用一些預先定義好的類時,我們在程序里採用的代碼是非常簡單和直觀的。
1.3 實現方案的隱藏
為方便後面的討論,讓我們先對這一領域的從業人員作一下分類。從根本上說,大致有兩方面的人員涉足面向對象的編程:「類創建者」(創建新數據類型的人)以及「客戶程序員」(在自己的應用程序中採用現成數據類型的人;注釋④)。對客戶程序員來講,最主要的目標就是收集一個充斥著各種類的編程「工具箱」,以便快速開發符合自己要求的應用。而對類創建者來說,他們的目標則是從頭構建一個類,只向客戶程序員開放有必要開放的東西(介面),其他所有細節都隱藏起來。為什麼要這樣做?隱藏之後,客戶程序員就不能接觸和改變那些細節,所以原創者不用擔心自己的作品會受到非法修改,可確保它們不會對其他人造成影響。
④:感謝我的朋友Scott Meyers,是他幫我起了這個名字。
「介面」(Interface)規定了可對一個特定的對象發出哪些請求。然而,必須在某個地方存在著一些代碼,以便滿足這些請求。這些代碼與那些隱藏起來的數據便叫作「隱藏的實現」。站在程式化程序編寫(Proceral Programming)的角度,整個問題並不顯得復雜。一種類型含有與每種可能的請求關聯起來的函數。一旦向對象發出一個特定的請求,就會調用那個函數。我們通常將這個過程總結為向對象「發送一條消息」(提出一個請求)。對象的職責就是決定如何對這條消息作出反應(執行相應的代碼)。
對於任何關系,重要一點是讓牽連到的所有成員都遵守相同的規則。創建一個庫時,相當於同客戶程序員建立了一種關系。對方也是程序員,但他們的目標是組合出一個特定的應用(程序),或者用您的庫構建一個更大的庫。
若任何人都能使用一個類的所有成員,那麼客戶程序員可對那個類做任何事情,沒有辦法強制他們遵守任何約束。即便非常不願客戶程序員直接操作類內包含的一些成員,但倘若未進行訪問控制,就沒有辦法阻止這一情況的發生——所有東西都會暴露無遺。
有兩方面的原因促使我們控制對成員的訪問。第一個原因是防止程序員接觸他們不該接觸的東西——通常是內部數據類型的設計思想。若只是為了解決特定的問題,用戶只需操作介面即可,毋需明白這些信息。我們向用戶提供的實際是一種服務,因為他們很容易就可看出哪些對自己非常重要,以及哪些可忽略不計。
進行訪問控制的第二個原因是允許庫設計人員修改內部結構,不用擔心它會對客戶程序員造成什麼影響。例如,我們最開始可能設計了一個形式簡單的類,以便簡化開發。以後又決定進行改寫,使其更快地運行。若介面與實現方法早已隔離開,並分別受到保護,就可放心做到這一點,只要求用戶重新鏈接一下即可。
Java採用三個顯式(明確)關鍵字以及一個隱式(暗示)關鍵字來設置類邊界:public,private,protected以及暗示性的friendly。若未明確指定其他關鍵字,則默認為後者。這些關鍵字的使用和含義都是相當直觀的,它們決定了誰能使用後續的定義內容。「public」(公共)意味著後續的定義任何人均可使用。而在另一方面,「private」(私有)意味著除您自己、類型的創建者以及那個類型的內部函數成員,其他任何人都不能訪問後續的定義信息。private在您與客戶程序員之間豎起了一堵牆。若有人試圖訪問私有成員,就會得到一個編譯期錯誤。「friendly」(友好的)涉及「包裝」或「封裝」(Package)的概念——即Java用來構建庫的方法。若某樣東西是「友好的」,意味著它只能在這個包裝的范圍內使用(所以這一訪問級別有時也叫作「包裝訪問」)。「protected」(受保護的)與「private」相似,只是一個繼承的類可訪問受保護的成員,但不能訪問私有成員。繼承的問題不久就要談到。
1.4 方案的重復使用
創建並測試好一個類後,它應(從理想的角度)代表一個有用的代碼單位。但並不象許多人希望的那樣,這種重復使用的能力並不容易實現;它要求較多的經驗以及洞察力,這樣才能設計出一個好的方案,才有可能重復使用。
許多人認為代碼或設計方案的重復使用是面向對象的程序設計提供的最偉大的一種杠桿。
為重復使用一個類,最簡單的辦法是僅直接使用那個類的對象。但同時也能將那個類的一個對象置入一個新類。我們把這叫作「創建一個成員對象」。新類可由任意數量和類型的其他對象構成。無論如何,只要新類達到了設計要求即可。這個概念叫作「組織」——在現有類的基礎上組織一個新類。有時,我們也將組織稱作「包含」關系,比如「一輛車包含了一個變速箱」。
對象的組織具有極大的靈活性。新類的「成員對象」通常設為「私有」(Private),使用這個類的客戶程序員不能訪問它們。這樣一來,我們可在不幹擾客戶代碼的前提下,從容地修改那些成員。也可以在「運行期」更改成員,這進一步增大了靈活性。後面要講到的「繼承」並不具備這種靈活性,因為編譯器必須對通過繼承創建的類加以限制。
由於繼承的重要性,所以在面向對象的程序設計中,它經常被重點強調。作為新加入這一領域的程序員,或許早已先入為主地認為「繼承應當隨處可見」。沿這種思路產生的設計將是非常笨拙的,會大大增加程序的復雜程度。相反,新建類的時候,首先應考慮「組織」對象;這樣做顯得更加簡單和靈活。利用對象的組織,我們的設計可保持清爽。一旦需要用到繼承,就會明顯意識到這一點。
1.5 繼承:重新使用介面
就其本身來說,對象的概念可為我們帶來極大的便利。它在概念上允許我們將各式各樣數據和功能封裝到一起。這樣便可恰當表達「問題空間」的概念,不用刻意遵照基礎機器的表達方式。在程序設計語言中,這些概念則反映為具體的數據類型(使用class關鍵字)。
我們費盡心思做出一種數據類型後,假如不得不又新建一種類型,令其實現大致相同的功能,那會是一件非常令人灰心的事情。但若能利用現成的數據類型,對其進行「克隆」,再根據情況進行添加和修改,情況就顯得理想多了。「繼承」正是針對這個目標而設計的。但繼承並不完全等價於克隆。在繼承過程中,若原始類(正式名稱叫作基礎類、超類或父類)發生了變化,修改過的「克隆」類(正式名稱叫作繼承類或者子類)也會反映出這種變化。在Java語言中,繼承是通過extends關鍵字實現的
使用繼承時,相當於創建了一個新類。這個新類不僅包含了現有類型的所有成員(盡管private成員被隱藏起來,且不能訪問),但更重要的是,它復制了基礎類的介面。也就是說,可向基礎類的對象發送的所有消息亦可原樣發給衍生類的對象。根據可以發送的消息,我們能知道類的類型。這意味著衍生類具有與基礎類相同的類型!為真正理解面向對象程序設計的含義,首先必須認識到這種類型的等價關系。
由於基礎類和衍生類具有相同的介面,所以那個介面必須進行特殊的設計。也就是說,對象接收到一條特定的消息後,必須有一個「方法」能夠執行。若只是簡單地繼承一個類,並不做其他任何事情,來自基礎類介面的方法就會直接照搬到衍生類。這意味著衍生類的對象不僅有相同的類型,也有同樣的行為,這一後果通常是我們不願見到的。
有兩種做法可將新得的衍生類與原來的基礎類區分開。第一種做法十分簡單:為衍生類添加新函數(功能)。這些新函數並非基礎類介面的一部分。進行這種處理時,一般都是意識到基礎類不能滿足我們的要求,所以需要添加更多的函數。這是一種最簡單、最基本的繼承用法,大多數時候都可完美地解決我們的問題。然而,事先還是要仔細調查自己的基礎類是否真的需要這些額外的函數。
1.5.1 改善基礎類
盡管extends關鍵字暗示著我們要為介面「擴展」新功能,但實情並非肯定如此。為區分我們的新類,第二個辦法是改變基礎類一個現有函數的行為。我們將其稱作「改善」那個函數。
為改善一個函數,只需為衍生類的函數建立一個新定義即可。我們的目標是:「盡管使用的函數介面未變,但它的新版本具有不同的表現」。
1.5.2 等價與類似關系
針對繼承可能會產生這樣的一個爭論:繼承只能改善原基礎類的函數嗎?若答案是肯定的,則衍生類型就是與基礎類完全相同的類型,因為都擁有完全相同的介面。這樣造成的結果就是:我們完全能夠將衍生類的一個對象換成基礎類的一個對象!可將其想像成一種「純替換」。在某種意義上,這是進行繼承的一種理想方式。此時,我們通常認為基礎類和衍生類之間存在一種「等價」關系——因為我們可以理直氣壯地說:「圓就是一種幾何形狀」。為了對繼承進行測試,一個辦法就是看看自己是否能把它們套入這種「等價」關系中,看看是否有意義。
但在許多時候,我們必須為衍生類型加入新的介面元素。所以不僅擴展了介面,也創建了一種新類型。這種新類型仍可替換成基礎類型,但這種替換並不是完美的,因為不可在基礎類里訪問新函數。我們將其稱作「類似」關系;新類型擁有舊類型的介面,但也包含了其他函數,所以不能說它們是完全等價的。舉個例子來說,讓我們考慮一下製冷機的情況。假定我們的房間連好了用於製冷的各種控制器;也就是說,我們已擁有必要的「介面」來控制製冷。現在假設機器出了故障,我們把它換成一台新型的冷、熱兩用空調,冬天和夏天均可使用。冷、熱空調「類似」製冷機,但能做更多的事情。由於我們的房間只安裝了控制製冷的設備,所以它們只限於同新機器的製冷部分打交道。新機器的介面已得到了擴展,但現有的系統並不知道除原始介面以外的任何東西。
認識了等價與類似的區別後,再進行替換時就會有把握得多。盡管大多數時候「純替換」已經足夠,但您會發現在某些情況下,仍然有明顯的理由需要在衍生類的基礎上增添新功能。通過前面對這兩種情況的討論,相信大家已心中有數該如何做。
1.6 多形對象的互換使用
通常,繼承最終會以創建一系列類收場,所有類都建立在統一的介面基礎上。我們用一幅顛倒的樹形圖來闡明這一點(注釋⑤):
⑤:這兒採用了「統一記號法」,本書將主要採用這種方法。
對這樣的一系列類,我們要進行的一項重要處理就是將衍生類的對象當作基礎類的一個對象對待。這一點是非常重要的,因為它意味著我們只需編寫單一的代碼,令其忽略類型的特定細節,只與基礎類打交道。這樣一來,那些代碼就可與類型信息分開。所以更易編寫,也更易理解。此外,若通過繼承增添了一種新類型,如「三角形」,那麼我們為「幾何形狀」新類型編寫的代碼會象在舊類型里一樣良好地工作。所以說程序具備了「擴展能力」,具有「擴展性」。
以上面的例子為基礎,假設我們用Java寫了這樣一個函數:
void doStuff(Shape s) {
s.erase();
// ...
s.draw();
}
這個函數可與任何「幾何形狀」(Shape)通信,所以完全獨立於它要描繪(draw)和刪除(erase)的任何特定類型的對象。如果我們在其他一些程序里使用doStuff()函數:
Circle c = new Circle();
Triangle t = new Triangle();
Line l = new Line();
doStuff;
doStuff;
doStuff;
那麼對doStuff()的調用會自動良好地工作,無論對象的具體類型是什麼。
這實際是一個非常有用的編程技巧。請考慮下面這行代碼:
doStuff;
此時,一個Circle(圓)句柄傳遞給一個本來期待Shape(形狀)句柄的函數。由於圓是一種幾何形狀,所以doStuff()能正確地進行處理。也就是說,凡是doStuff()能發給一個Shape的消息,Circle也能接收。所以這樣做是安全的,不會造成錯誤。
我們將這種把衍生類型當作它的基本類型處理的過程叫作「Upcasting」(上溯造型)。其中,「cast」(造型)是指根據一個現成的模型創建;而「Up」(向上)表明繼承的方向是從「上面」來的——即基礎類位於頂部,而衍生類在下方展開。所以,根據基礎類進行造型就是一個從上面繼承的過程,即「Upcasting」。
在面向對象的程序里,通常都要用到上溯造型技術。這是避免去調查准確類型的一個好辦法。請看看doStuff()里的代碼:
s.erase();
// ...
s.draw();
注意它並未這樣表達:「如果你是一個Circle,就這樣做;如果你是一個Square,就那樣做;等等」。若那樣編寫代碼,就需檢查一個Shape所有可能的類型,如圓、矩形等等。這顯然是非常麻煩的,而且每次添加了一種新的Shape類型後,都要相應地進行修改。在這兒,我們只需說:「你是一種幾何形狀,我知道你能將自己刪掉,即erase();請自己採取那個行動,並自己去控制所有的細節吧。」
1.6.1 動態綁定
在doStuff()的代碼里,最讓人吃驚的是盡管我們沒作出任何特殊指示,採取的操作也是完全正確和恰當的。我們知道,為Circle調用draw()時執行的代碼與為一個Square或Line調用draw()時執行的代碼是不同的。但在將draw()消息發給一個匿名Shape時,根據Shape句柄當時連接的實際類型,會相應地採取正確的操作。這當然令人驚訝,因為當Java編譯器為doStuff()編譯代碼時,它並不知道自己要操作的准確類型是什麼。盡管我們確實可以保證最終會為Shape調用erase(),為Shape調用draw(),但並不能保證為特定的Circle,Square或者Line調用什麼。然而最後採取的操作同樣是正確的,這是怎麼做到的呢?
將一條消息發給對象時,如果並不知道對方的具體類型是什麼,但採取的行動同樣是正確的,這種情況就叫作「多形性」(Polymorphism)。對面向對象的程序設計語言來說,它們用以實現多形性的方法叫作「動態綁定」。編譯器和運行期系統會負責對所有細節的控制;我們只需知道會發生什麼事情,而且更重要的是,如何利用它幫助自己設計程序。
有些語言要求我們用一個特殊的關鍵字來允許動態綁定。在C++中,這個關鍵字是virtual。在Java中,我們則完全不必記住添加一個關鍵字,因為函數的動態綁定是自動進行的。所以在將一條消息發給對象時,我們完全可以肯定對象會採取正確的行動,即使其中涉及上溯造型之類的處理。
1.6.2 抽象的基礎類和介面
設計程序時,我們經常都希望基礎類只為自己的衍生類提供一個介面。也就是說,我們不想其他任何人實際創建基礎類的一個對象,只對上溯造型成它,以便使用它們的介面。為達到這個目的,需要把那個類變成「抽象」的——使用abstract關鍵字。若有人試圖創建抽象類的一個對象,編譯器就會阻止他們。這種工具可有效強制實行一種特殊的設計。
亦可用abstract關鍵字描述一個尚未實現的方法——作為一個「根」使用,指出:「這是適用於從這個類繼承的所有類型的一個介面函數,但目前尚沒有對它進行任何形式的實現。」抽象方法也許只能在一個抽象類里創建。繼承了一個類後,那個方法就必須實現,否則繼承的類也會變成「抽象」類。通過創建一個抽象方法,我們可以將一個方法置入介面中,不必再為那個方法提供可能毫無意義的主體代碼。
interface(介面)關鍵字將抽象類的概念更延伸了一步,它完全禁止了所有的函數定義。「介面」是一種相當有效和常用的工具。另外如果自己願意,亦可將多個介面都合並到一起(不能從多個普通class或abstract class中繼承)。
1.7 對象的創建和存在時間
從技術角度說,OOP(面向對象程序設計)只是涉及抽象的數據類型、繼承以及多形性,但另一些問題也可能顯得非常重要。本節將就這些問題進行探討。
最重要的問題之一是對象的創建及破壞方式。對象需要的數據位於哪兒,如何控制對象的「存在時間」呢?針對這個問題,解決的方案是各異其趣的。C++認為程序的執行效率是最重要的一個問題,所以它允許程序員作出選擇。為獲得最快的運行速度,存儲以及存在時間可在編寫程序時決定,只需將對象放置在堆棧(有時也叫作自動或定域變數)或者靜態存儲區域即可。這樣便為存儲空間的分配和釋放提供了一個優先順序。某些情況下,這種優先順序的控制是非常有價值的。然而,我們同時也犧牲了靈活性,因為在編寫程序時,必須知道對象的准確的數量、存在時間、以及類型。如果要解決的是一個較常規的問題,如計算機輔助設計、倉儲管理或者空中交通控制,這一方法就顯得太局限了。
第二個方法是在一個內存池中動態創建對象,該內存池亦叫「堆」或者「內存堆」。若採用這種方式,除非進入運行期,否則根本不知道到底需要多少個對象,也不知道它們的存在時間有多長,以及准確的類型是什麼。這些參數都在程序正式運行時才決定的。若需一個新對象,只需在需要它的時候在內存堆里簡單地創建它即可。由於存儲空間的管理是運行期間動態進行的,所以在內存堆里分配存儲空間的時間比在堆棧里創建的時間長得多(在堆棧里創建存
『肆』 初級程序員應該如何鍛煉自己的邏輯思維和思考能力
對於初級程序員要想提高這兩方面的能力,最好的辦法就是解剖麻雀——向前人的經典案例學習。
初級程序員還不需要完成高難度的突破,需要做的是掌握基礎知識,了解前人遇到了哪些問題,他們是如何思考和解決的,
多看多思考,經常動手做,就會大幅度提高自己這兩方面的能力的。
『伍』 程序員應該如何提升自己
程序員在學習過程中應該如何提升自己呢?在了解多數的編程知識之後,很多書籍都是新手從零開始學習。那麼對於有基礎的程序員來說,應該如何加深自己的知識,如何讓自己具備最佳的編寫代碼方法呢?下面電腦培訓為大家介紹程序員提升自己的方法。
一、通過編程挑戰實踐
很多人都喜歡編程方面的挑戰,但是總的來說,現在不適合去找一種新的編程語言。它們可以提供一種弱反饋迴路,程序要麼產生正常的輸出要麼沒有產生,不會給設計過程進行反饋。這樣的方法可能會引入一個新的演算法和不成熟的語言,在實踐中非常的薄弱。IT培訓認為這樣的方法更加傾向於表現而不是練習,所以你需要處理的不是人為問題,而是真實問題。
二、做業余項目
做業余項目,如果你有業余項目的話,投入編程實踐是一個很好的方法。不幸的是,由於項目參差不齊,你可能什麼也學不到。如果你的業余項目與你想學的程序是一致的,那麼恭喜你,這是一個很好的選擇,否則它只是另一個版本的表現與實踐。即使在最好的情況下,如果主要的目標是產生一些東西,那麼北大青鳥認為這就意味著實踐和學習是落後的。
三、閱讀編程實踐的書籍
從編程書上,您可以更快地了解知識。這被認為是幾乎所有改進編程程序的一部分。但是,這不是每個人都能接受的。純粹的知識獲取能夠幫助你知道什麼樣的可用選項,當你遇到問題時,昆明北大青鳥認為知識是不能取代更好的心理模型的。
『陸』 程序員的編程思想怎麼培養
多看書,多編程,多世間,多學習,站在巨人的肩膀上,同時也要多問,敏而好學,不恥下問。推薦一本書《java編程思想》相信看了之後會有很大的啟發
『柒』 初學者JAVA程序員怎樣快速提升自己技術
一、提升對java技術的思考
很多人口裡嚷著要提升java技術,行動也有,但就是不奏效,是怎麼回事呢?因為行動前沒有好好的思考,比如老是盯著已經掌握熟練的java技術練習,你為什麼不考慮多練練你不熟習的java技術呢?那麼應該思考些什麼關於java技術的問題呢?
1、這個技術能解決什麼問題(why)
2、比較適合在哪些場景應用(where+when)
3、這個技術跟我已經掌握的哪個知識或技能類似,有什麼差別、有什麼特點、有什麼優點和缺點(what)
4、了解前面的問題後,你在開始考慮提升java技術那麼效果會比較好。
二、善於模仿,把他人的變成你的
你的代碼剛開始是怎麼學會的呢?不外乎模仿,但是模仿也有訣竅,有的人模仿的快,有的人模仿的慢。時常強調,多去看看其他人的代碼是怎麼編寫的,你可以從其他人的代碼中模仿出很多的東西,甚至你可以嘗試去修改其他人的代碼,讓它跟你的想法更加接近,看看你下次是不是可以這樣做,看看學習效率有沒有提高或者變得簡單,長此以往,你的java技術一定會有質的提升。
『捌』 程序員如何掌握編程思想
作為一個有經驗的程序員,首先應該能夠自如地使用標準的程序流程圖(記住:從軟體工程的角度上講,任何一個再復雜的軟體都可以由:順序、選擇、循環結構來表示)把自己頭腦中的編程思想體現在紙上,然後再根據紙上的程序流程圖進行模塊化的編寫程序,並且一邊進行模塊化的編寫程序、一邊進行調試程序,直到最後調試通過、得出正確的運行結果為止。
『玖』 程序員的邏輯思維可以從哪些方面進行培養呢
程序員邏輯思維的培養對軟體工程非常重要,思維快的能快速編寫邏輯代碼。可以從一下幾個方面進行慢慢培養。
第一:明確學習目的
邏輯思維學習編程對多數IT業人員來說都是非常有用的。學編程,做一名編程人員,從個人角度講,可以解決在軟體使用中所遇到的問題,改進現有軟體,可以為自己找到一份理想的工作添加重要得砝碼,有利於在求職道路上謀得一個好的職位;從國家的角度,可以為中國的軟體產業做出應有的貢獻,一名優秀的程序員永遠是被爭奪的對象。學習編程還能鍛煉思維,使我們的邏輯思維更加嚴密;能夠不斷享受到創新的樂趣,將一直有機會走在高科技的前沿,因為程序設計本身是一種創造性的工作。知識經濟時代給我們帶來了無限的機會,要想真正掌握計算機技術,並在IT行業里干出一番事業來,有所作為,具有一定的編程能力是一個基本條件和要求。
第二打好基礎,學好基礎知識對我們開發也很重要學編程要具備一定的基礎,總結之有以下幾方面:
首先是數學基礎 從計算機發展和應用的歷史來看計算機的數學模型和體系結構等都是有數學家提出的,最早的計算機也是為數值計算而設計的。因此,要學好計算機就要有一定的數學基礎,出學者有高中水平就差不多了。
其次是邏輯思維能力的培養 學程序設計要有一定的邏輯思維能力,「邏思力」的培養要長時間的實踐鍛煉。要想成為一名優秀的程序員,最重要的是掌握編程思想。要做到這一點必須在反復的實踐、觀察、分析、比較、總結中逐漸地積累。因此在學習編程過程中,我們不必等到什麼都完全明白了才去動手實踐,只要明白了大概,就要敢於自己動手去體驗。誰都有第一次。有些問題只有通過實踐後才能明白,也只有實踐才能把老師和書上的知識變成自己的,高手都是這樣成材的。最後是選擇一種合適的入門語言 面對各種各樣的語言,應按什麼樣的順序學呢?程序設計工具不外乎如下幾類: 1)本地開發 應用軟體開發的工具有:Visual Basic 、Delphi 、VC++ ( C++ Builder ) 等;資料庫開發工具有:Visual Foxpro 、Oracle Developer 、Power Builder 等。 2)跨平台開發 開發工具如 Java 等。 3)網路開發 對客戶端開發工具如:Java Script 等;對伺服器開發工具如:PHP 、ASP 、JSP 、ISAPI 、NSAPI 、CGI 等。 以上不同的環境下幾種開發工具中 VB 法簡單並容易理解,界面設計是可設化的,易學、易用。選 VB 作為入門的方向對出學者是較為適合的。
第三:注意理解一些重要概念
一本程序設計的書看到的無非就是變數、函數、條件語句、循環語句等概念,但要真正能進行編程應用,需要深入理解這些概念,在理解的基礎上應用,不要只簡單地學習語法、結構,而要吃透針對這些語法、結構的應用例子,做到舉一反三,觸類旁通。
第四:掌握編程思想,編程思想使用較多的就是oop編程思想
學習一門語言或開發工具,語法結構、功能調用是次要的,最主要是學習它的思想。例如學習 VC 就要學習 Windows 的內在機理、什麼是線程......;學習 COM 就要知道VTALBE 、類廠、介面、idl......,關鍵是學一種思想,有了思想,那麼我們就可以觸類旁通。
第六:多實踐、多交流,一切思維來自項目開發的積累
掌握編程思想必須在編程實際工作中去實踐和體會。編程起步階段要經常自己動手設計程序,具體設計時不要拘泥於固定的思維方式,遇到問題要多想幾種解決的方案。這就要多交流,各人的思維方式不同、角度各異,各有高招,通過交流可不斷吸收別人的長處,豐富編程實踐,幫助自己提高水平。親自動手進行程序設計是創造性思維應用的體現,也是培養邏輯思維的好方法。
第七:養成良好的編程習慣
編程入門不難,但入門後不斷學習是十分重要的,相對來說較為漫長。在此期間要注意養成一些良好的編程習慣。編程風格的好壞很大程度影響程序質量。良好的編程風格可以使
程序結構清晰合理,且使程序代碼便於維護。如代碼的縮進編排、變數命令規則的一致性、代碼的注釋等。
第八:上網學編程
在網上可以學到很多不同的編程思想、方法、經驗和技巧,有大量的工具和作品及相關的輔導材料供下載
8.加強計算機理論知識的再學習
思維培養學編程是符合「理論→實踐→再理論→再實踐」的一個認識過程。一開始要具有一定的計算機理論基礎知識,包括編程所需的數學基礎知識,具備了入門的條件,就可以
開始編程的實踐,從實踐中可以發現問題需要加強計算機理論知識的再學習。程序人人皆可編,但當你發現編到一定程度很難再提高的時候,就要回頭來學習一些計算機科學和數
學基礎理論。學過之後,很多以前遇到的問題都會迎刃而解,使人有豁然開朗之感。因此在學習編程的過程中要不斷地針對應用中的困惑和問題深入學習數據結構、演算法、計算機
原理、編譯原理、操作系統原理、軟體工程等計算機科學的理論基礎和數理邏輯、代數系統、圖論、離散數學等數學理論基礎知識。這樣經過不斷的學習,再努力地實踐,編程水平一定會不斷提高到一個新高度。
這就是總結出來的思維培養模式,希望能幫到你,謝謝!