面向对象程序设计小结 2020/2/13

目前总结来说,觉得面向过程和面向对象编程的区别是:视角

面向过程编程时要用上帝视角去看每一个操作。

面向对象则是在编程时要把自己站在类的角度去思考每一个行为。

 

做了一个细胞自动机的程序,来自浙大翁恺老师的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,对二者协调,而二者之间被分离。

关于细胞自动机:

细胞自动机(或是说最早的生命游戏)是个很厉害的东西。体现了一个道理,十分复杂的行为背后可能仅仅只是由非常简单的规则所支配,如数学世界的元规则就是公理,有人甚至认为世界就是个计算机程序(量子的?)?。这么一想,貌似编程也就像是在创造一个程序的世界,正如同创造这自动运行的细胞自动机一样。

想起来一句话,”你认为艾欧泽亚大陆存在真实吗?"

我的回答是肯定的。

 

 

 

 

 

 

 

你可能感兴趣的:(开发)