首页 > 代码库 > 面向对象先导学习笔记

面向对象先导学习笔记

面向对象先导学习笔记

经过了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树相比,无论是运行的速度和程序的稳定性方面都有所提高,而且大大简化了程序设计的步骤。在对 HashMap 按 key 进行遍历时,可以按以下方法: 

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)。 在涉及到重写时,应当适当利用 super 和 this 关键词,以防止调用与设想中不同的方法,减少错误的出现。

封装

在这一部分,主要的内容是利用 public  ,  protected 和 private 三种关键字,对数据和方法进行隐藏,以提高程序的安全性。

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

意见和建议

  1. 在最初一节课上,首要的感觉就是懵,不明白需要做什么,不明白布置的要求如何完成。在完成坏境的配置后,经过一些讲解,直接要求完成一些任务,但是此时之前并没有接触过任何Java语法的我感觉无从下手,前两个任务在助教的帮助下才能完成,而后面的任务,更多的涉及到Java的方法等,当时完全没有了解,完全不能跟上进度。希望在下次开课时,能够强化对于基础语法的讲解,在开始完成任务前的讲解的课件中能够提供示例程序。在完成一个任务后,提供相应的标程以作参考。
  2. 在课后完成作业时,感觉主要的问题就是作业要求的不明确,难以上手,以及作业要求的朝令夕改。

通过本次课程的学习,我初步掌握了Java的语法,能够完成一些较为初步的工程任务,加深了对于面向对象的了解,相信对于大二下学期面向对象的学习都将有所帮助。

面向对象先导学习笔记