1. 程式人生 > >面向對象先導學習筆記

面向對象先導學習筆記

可見度 限制 python def 運行 scan 而且 自底向上 沒有

面向對象先導學習筆記

經過了Python、C語言和數據結構的學習,感覺對於Java這門新學習的語言上手速度明顯快了許多。在學習Java的過程中,個人覺得Java的語法規則在很大程度上與C類似,但是在設計程序和具體實現的過程中,更偏向於Python的思路,尤其是對於方法的調用和自帶數據結構的使用方面。

數據類型的Java實現

Java自帶了大量的數據類型,在完成作業的過程中,個人嘗試通過手寫二叉樹完成問題,但是與Java自帶的數據結構相比,無論是在穩定性和運行速度方面都有所欠缺。但是通過自己的摸索和嘗試,在一定程度上加深了對於數據結構本身和Java語法的了解。

例如,以二叉樹為例,C語言的二叉樹構造方法如下:

1 typedef struct Btree
2 {
3     int n;
4     struct Btree *lnode, *rnode;
5 }btree;

在C語言中,左右子樹是依靠指針,將地址存儲在節點中,而在Java中沒有指針的概念,但是可以在類中包含同一個類的數據,在C語言中,在 struct 中包含同一個 struct 類型的數據是不被允許的。Java實現二叉樹時,直接在節點中存儲左右節點本身,使用層層嵌套的方式實現二叉樹。

 1 public class Node
 2 {
 3     int n;
 4     Node lnode;
 5     Node rnode;
6 public Node() 7 { 8 this.n = 0; 9 this.lnode = null; 10 this.rnode = null; 11 } 12 }

以二叉樹為例,其它數據類型的構造方法與此類似,涉及到的算法大同小異,下面是Java構造的BST樹及其在進行插入、查找和遍歷等操作時的算法:

  1 import java.util.Vector;
  2 
  3 public class Node
  4 {
  5     int n;
  6     Node lnode;
  7     Node rnode;
8 public Node() 9 { 10 this.n = 0; 11 this.lnode = null; 12 this.rnode = null; 13 } 14 15 public int cmp(int s) 16 { 17 if (n < s) 18 return -1; 19 else if (n == s) 20 return 0; 21 else 22 return 1; 23 } 24 25 public Node getLnode() 26 { 27 return this.lnode; 28 } 29 30 public Node getRnode() 31 { 32 return this.rnode; 33 } 34 35 public Node setLnode(Node s) 36 { 37 this.lnode = s; 38 return this.lnode; 39 } 40 41 public Node setRnode(Node s) 42 { 43 this.rnode = s; 44 return this.rnode; 45 } 46 47 } 48 49 50 public class BST 51 { 52 Node root; 53 54 public BST() 55 { 56 this.root = null; 57 } 58 59 public BST(Node r) 60 { 61 this.root = r; 62 } 63 64 public void insert(Node p, int i) 65 { 66 if (this.root == null) 67 { 68 this.root = new Node(i); 69 return; 70 } 71 else 72 { 73 int result = p.cmp(i); 74 if (result > 0) 75 { 76 if (p.getLnode() == null) 77 { 78 Node r = new Node(i); 79 p.setLnode(r); 80 return; 81 } 82 else 83 insert(p.getLnode(), i); 84 } 85 else 86 { 87 if (p.getRnode() == null) 88 { 89 Node r = new Node(i); 90 p.setRnode(r); 91 return; 92 } 93 else 94 insert(p.getRnode(), i); 95 } 96 } 97 } 98 99 public void printTree(Node p) 100 { 101 if (p.getLnode() != null) 102 { 103 printTree(p.getLnode()); 104 } 105 p.print();//打印該節點數據 106 if (p.getRnode() != null) 107 { 108 printTree(p.getRnode()); 109 } 110 return; 111 } 112 113 public void search(Node p, String s) 114 { 115 if (p == null) 116 { 117 return; 118 } 119 else 120 { 121 if (p.cmp(s) > 0) 122 { 123 // 查左子樹 124 search(p.getLnode(), s); 125 } 126 else if (p.cmp(s) < 0) 127 { 128 // 查右子樹 129 search(p.getRnode(), s); 130 } 131 else 132 { 133 // 找到該值 134 p.print(); 135 return; 136 } 137 } 138 } 139 140 }

Java的鍵盤/文件輸入

在完成課上和課下作業的過程中,Java的文件輸入和控制臺輸入同樣是一個新接觸到的內容,與C和Python相比較為繁瑣,經過搜索和學習,以 Scanner 為例的輸入實現方法如下: 在使用 Scanner 進行文件輸入之前,需要 import 以下三個包:

1 import java.io.FileInputStream;
2 import java.io.FileNotFoundException;
3 import java.util.Scanner;

第二個用於處理異常,同時需要在進行文件輸入操作的方法後添加異常情況處理,例如:

1 public static void main(String args[]) throws FileNotFoundException{...}

在執行操作時按照以下語法:

1 String name = "FILENAME";
2 FileInputStream inputStream = new FileInputStream(name);
3 Scanner scan = new Scanner(inputStream, "ASCII"/*"UTF-8"*/);

對於鍵盤輸入,只需 import Scanner 即可,創建 Scanner 的用法如下:

1 Scanner wordScanner = new Scanner(System.in);

在學習Java和完成作業的過程中,個人認為主要的難點在於從C語言到Java語言程序設計思路的轉換,在使用C語言進行程序設計時,完全是依靠自己的思路,自底向上實現程序的每一個部分,而使用Java時,更多的要關註自己的想法與Java的內嵌數據類型和方法的契合度,並適當做出改變以更好的利用已有的方法。在完成最初一兩次的作業時,很少使用Java自帶的方法,在逐漸熟悉之後才開始較為熟練的查找方法和使用。

例如在完成第四次作業時使用的 HashMap ,與最初的構想並不完全相同,最終使用了嵌套的方式,將首單詞、末單詞和詞頻三個數據進行了存儲。

第四次作業中使用了 HashMap 這一數據類型,與第三次手寫的BST樹相比,無論是運行的速度和程序的穩定性方面都有所提高,而且大大簡化了程序設計的步驟。在對 HashMapkey 進行遍歷時,可以按以下方法:

1  for(String key: this.node.keySet()) {...} 

除此之外,在完成作業的過程中,Java對於數組長度的限制與C相比更為嚴格,如果數組容量過小,可能會導致數組越界的問題,如果過大也有可能導致爆內存,同時,Java沒有C語言的內存分配。Java在實現動態數組時,可以使用 Vector 容器類。 使用時,需要首先進行 import

1 import java.util.Vector; 

Vector 內容納的應該為 class 對象,因此需要創建整數數組時,應該創建 Vector<Integer> ,如下所示:

1 Vector<Integer> v;
2 v = new Vector<Integer>();

在學習的過程中,另一個比較難以理解的地方是接口,利用接口,可以間接實現Java本身所不支持的多重繼承,此外也可以簡化代碼,體現了面向對象特性中的抽象。
接口的聲明語法格式如下:

1 [可見度] interface 接口名稱 [extends 其他的類名] 
2 {
3         // 聲明變量
4         // 抽象方法
5 }

當類實現接口的時候,類要實現接口中所有的方法。否則,類必須聲明為抽象的類。

類使用 implements 關鍵字實現接口。在類聲明中, Implements 關鍵字放在 class 聲明後面。

實現一個接口的語法,可以使用這個公式:

1 ...implements 接口名稱[, 其他接口, 其他接口..., ...] ... 

對於實現同一個接口的不同類,如果給同一個方法傳遞的數據類型不同,可以統一使用所有類型的父類: Object ,然後在方法內部具體判斷是哪一種類型。


之前在學習Python的過程中便已經對面向對象有了初步的了解,但是更多的還是使用Python面向過程的部分來完成作業,對於面向對象的理解並不深。通過本門課程的學習,以Java這門完全面向對象的語言為工具,在學習了一門新語言的基礎上,進一步加深了對於面向對象的理解,能夠較為準確的完成作業,對於面向對象的特征:繼承,封裝和多態有了一些理解和體會。

繼承

使用繼承,子類就不會存在與父類重復的代碼,維護性也提高,代碼也更加簡潔,提高代碼的復用性。

多態

在完成作業的過程中,對於多態的涉及較少,對於多態的三種實現方法,重寫/重載、接口、抽象類和抽象方法,所使用的幾乎都是重寫(Override)與重載(Overload)。 在涉及到重寫時,應當適當利用 superthis 關鍵詞,以防止調用與設想中不同的方法,減少錯誤的出現。

封裝

在這一部分,主要的內容是利用 public , protectedprivate 三種關鍵字,對數據和方法進行隱藏,以提高程序的安全性。

private 只能在其自己的定義類中使用,而 public 可以在所有的類中使用。 protected 能夠在自已的定義類以及其子類中使用。

意見和建議

  1. 在最初一節課上,首要的感覺就是懵,不明白需要做什麽,不明白布置的要求如何完成。在完成壞境的配置後,經過一些講解,直接要求完成一些任務,但是此時之前並沒有接觸過任何Java語法的我感覺無從下手,前兩個任務在助教的幫助下才能完成,而後面的任務,更多的涉及到Java的方法等,當時完全沒有了解,完全不能跟上進度。希望在下次開課時,能夠強化對於基礎語法的講解,在開始完成任務前的講解的課件中能夠提供示例程序。在完成一個任務後,提供相應的標程以作參考。
  2. 在課後完成作業時,感覺主要的問題就是作業要求的不明確,難以上手,以及作業要求的朝令夕改。

通過本次課程的學習,我初步掌握了Java的語法,能夠完成一些較為初步的工程任務,加深了對於面向對象的了解,相信對於大二下學期面向對象的學習都將有所幫助。

面向對象先導學習筆記