目前总结来说,觉得面向过程和面向对象编程的区别是:视角
面向过程编程时要用上帝视角去看每一个操作。
面向对象则是在编程时要把自己站在类的角度去思考每一个行为。
做了一个细胞自动机的程序,来自浙大翁恺老师的Java慕课。老师分别用的是“生命游戏”和“狐狸与兔子”。练习的就时候去找了一个森林火灾模型来做。来自这里:https://blog.csdn.net/qq_43434831/article/details/100146269
代码:
//forest_fire_model.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static java.lang.System.exit;
public class forest_fire_model {
private static int size=35;
private static int MAX_STEP=1000;
public static void main(String[] args){
MapData mapData= new MapData(size,size);
View view=new View(size,size,mapData);
int grid_size=Cell.getGridSize();
JFrame frame = new JFrame();
JButton button=new JButton("Next");
button.setSize(new Dimension(400,100));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setTitle("forest-disaster model");
frame.add(view);
frame.add(button, BorderLayout.NORTH);
frame.pack();
//frame.setSize(grid_size*size,grid_size*size*2);
frame.setVisible(true);
// for(int i=0;i{
mapData.next();
frame.repaint();
try{
Thread.sleep(200);
}catch(Exception ee){
exit(0);
}
});
}
}
//View.java
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
public class View extends JPanel {
private int L,W;
private MapData mapdata;
public View(int L,int W,MapData mapdata){
this.L=L;
this.W=W;
this.mapdata=mapdata;
}
@Override
public void paint(Graphics g){
super.paint(g);
for(int i=0;i
//MapData.java
import java.util.Random;
public class MapData {
private double map[][];
private int L,W;
private static double lowThresh=Thresh.lowThresh.getNum()
,highThresh=Thresh.highThresh.getNum()
,loss=2;
private static double lightingRatio=0.05,rebornRatio=0.2;
private static int dir[][]={
{-1,0},{0,1},{1,0},{0,-1}};
public MapData(int L,int W){
this.L=L; this.W=W;
map=new double[L][W];
for(int i=0;i=0&&rr=0&&cc
//Thresh.java
public enum Thresh {
lowThresh(20),highThresh(70);
private double num;
Thresh(double num) {this.num=num;}
double getNum(){return this.num;}
}
//Cell.java
import java.awt.*;
import java.awt.Graphics;
import java.util.Map;
import java.util.Random;
public class Cell {
private static int GRID_SIZE = 16;
private static MapData mp=new MapData();
public static int getGridSize() {
return GRID_SIZE;
}
private enum State{low,middle,high};
private State state;
Cell(double x){
double lowThresh=Thresh.lowThresh.getNum();
double highThresh=Thresh.highThresh.getNum();
if(x
采用MVC的模式,其中类model是class MapData,view是class forest_fire_model+class View+class Cell, controller是class forest_fire_model. (现在想来,写一个继承JFrame的类会更好,这样class forest_fire_model就不会有两个角色了)
重要的一点是:
当两个类有某一块有很大关联性时的做法。有三种方式:1.其中一个类直接创建另一个类的对象作为成员,即一个类对另一个类是完全可见的 2.新创建一个类/接口,让两者公共使用 3.创建一个新的类,同时含有这两个类的对象作为成员,即该新类对二者都完全可见。
其实可以说,在这三个细胞自动机程序中,这三类全都用到了。
对于第一种方式:"狐狸与兔子“中,在决定某个动物的行为时,程序中会有一个getSurround的函数,查看周围有哪些邻居并传给对象。这一点其实体现的是第一种方式,为什么一定要先这么做,而不是直接在程序中直接”看“某个格子周围有什么动物,然后决定它下一步的行为呢?认为前者正是面向对象编程,后者是面向过程编程。站在一个动物的角度上看,影响它的是它周围的几个格子上有什么东西,而它自然而然的行为就是看周围有什么东西然后做出下一步的决定。而后者是上帝视角了。
对于第二种方式:森林火灾模型中,在View和MapData实现过程中,三个状态(健康,燃烧,枯死)在视图和数据模型中是相关的,都要用到lowThresh,middleThresh,highThresh这三个常量。而其他的关联性确不大。本来想用接口存储常量,后来查过说是用接口存常量不利于Java的部分编译的特性,推荐用Enum类存储,于是学习了一下这个。
对于第三种方式: 这就像是MVC模式中controller和view以及model的关系了,controller中有view和frame,对二者协调,而二者之间被分离。
关于细胞自动机:
细胞自动机(或是说最早的生命游戏)是个很厉害的东西。体现了一个道理,十分复杂的行为背后可能仅仅只是由非常简单的规则所支配,如数学世界的元规则就是公理,有人甚至认为世界就是个计算机程序(量子的?)?。这么一想,貌似编程也就像是在创造一个程序的世界,正如同创造这自动运行的细胞自动机一样。
想起来一句话,”你认为艾欧泽亚大陆存在真实吗?"
我的回答是肯定的。