Skip to content

Latest commit

 

History

History
302 lines (209 loc) · 8.1 KB

第三章 类的创建.md

File metadata and controls

302 lines (209 loc) · 8.1 KB

第三章 类的创建

请先复制以下代码,在 PDE 中运行。

// Modify by akb4q
// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Example 7-3: Bouncing ball with functions

//实例声明
BouncingBall jsj;
BouncingBall hqm;

//程序初始
void setup() {
  size(640, 360);
  smooth();

  //实例初始化
  jsj = new BouncingBall(100, 100, 2.5, 1, 100);
  hqm = new BouncingBall(100, 100, 1, 1, 50);
}

//程序运行
void draw() {
  background(255);

  //调用对象方法
  jsj.move();
  jsj.display();

  hqm.move();
  hqm.display();
}


// 类定义
class BouncingBall {

  // 变量声明
  float locationX; // 位置
  float locationY;
  float xSpeed; // 速度
  float ySpeed;
  int diameter; // 大小

  // 构建 constructor
  BouncingBall(float _locationX, float _locationY, float _xSpeed, float _ySpeed, int _diameter) {

    // 把临时变量赋值给变量
    locationX = _locationX;
    locationY = _locationY;
    xSpeed = _xSpeed;
    ySpeed = _ySpeed;
    diameter = _diameter;
  }

  // 方法 method
  void move() {
    // Change the x location by speed
    locationX += xSpeed;
    locationY += ySpeed;


    // If we’ve reached an edge, reverse speed
    if ((locationX > width-diameter/2) || (locationX < 0+diameter/2)) {
      xSpeed *= -1;
    }

    if ((locationY >= height-diameter/2) || (locationY <= 0+diameter/2)) {
      ySpeed *= -1;
    }
  }

  void display() {
    stroke(0);
    fill(175);
    ellipse(locationX, locationY, diameter, diameter);
  }
}

伪代码

伪代码 pseudo-code 作为一种方法,可以有效的让程序架构思路清晰,往往在写代码之前,把整个架构用伪代码的方式写下来,但不是用于执行,而是让自己明了。对于初学者来说可以先有这个意识,但简短的任务,往往直接就上手了。

用伪代码来写一下以上的代码过程:

1.声明江山娇和红旗漫,做为两个弹球

2.江山娇大个一点,红旗漫瘦一点

3.江山娇运动,红旗漫也运动,但根据体型不同,可能移动的速度也有所不同. 当他们碰壁的时候,往相反的方向运动

4.他们就是这么虚无的在平面国里移动

OOP/类和对象

对于程序员来说,他们总是用上帝视角看待世界。

Object-oriented Programming (OOP) 是这种上帝视角的体现。不仅俯瞰整个类 class的世界,并且从内部去创建实例 Object

人类有那些共有的特征呢?有头有脚,吃喝拉撒,直立行走,能跑能跳。我作为人,所以我是人类的实例。比如我的身高、体重、等等这些都是我的参数。正是这些不同的参数造成了人类的多样性。 再比如车子,各种型号、牌子、功能等等,但基本结构是一个样的,都有四个轮子和一个车身。某个牌子的车子的某个型号就是汽车的实例。

为了更有效且方便地调用类,就有了 OOP 这种编程思路:

传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。 wikipedia

面向对象程序设计比传统的面向过程程序设计更有什么好处?

补充:我个人把 OOP 翻译为“实例导向”,但你在很多地方会看到“面向对象”,知道实同一件事就可以了。 翻译的问题很麻烦,但每个人应该有自己理解方式和态度。

Java 其实是一种 OOP 型的语言,可以把任何看作是类的实例。以后你会逐渐发现这点。

类的实例使用

在深入类之前,我们很快的看一下类在整个主程序中的使用方法。

// Step 1. Declare an object. 实例声明
BouncingBall jsj;

void setup()  {    
  // Step 2. Initialize object. 处始化实例
  jsj = new BouncingBall();   
}    

void draw()  {    
  background(255);  
  // Step 3. Call methods on the object.  调用实例的方法
  jsj.move();   
  jsj.display();   
}
  1. 在程序开头处声明实例
  2. setup()处初始化实例,使其成为实例
  3. draw() 里调用实例的方法

实例声名

我们从语法上可以做比一个比较:

int a; // 变量声明

BouncingBall jcj; // 实例声明

你会发现变量声明就是在创建某种数据类型的实例。声明a做为一个整数,同理BouncingBall类 class,而jsj实例 Object,也就是我们创建的对象。实例名可以随便取,和变量名一样,但惯例是小写。

初始化实例

在 setup() 里,我们要把具体的 arguments 给进去。

//初始化对象
jcj = new BouncingBall(100, 100, 2.5, 1, 100);

当程序帧运行到这的时候,程序会跳到类的程序块部分,这个类取名为 “BouncingBall”, 通常类名会首字母大写或者全部大写,以区别对象的小写。这是类的命名惯例。

实例方法的调用

jsj.move();   
jsj.display();

在实例名后通过.方法名() 的语法调用方法。会发现方法和函数类似。但是也请注意关于方法 method 和函数 function 的区分在类的语境下,我们惯例称为方法 method

类的结构

整个类程序块由这四部分组成

  1. 定义取名
  2. 变量声名
  3. 函数构建
  4. 创建方法
// 类定义
class BouncingBall {  // 定义取名

  // 变量声明
  float locationX; // 位置
  float locationY;
  float xSpeed; // 速度
  float ySpeed;
  int diameter; // 大小

  // 构建 constructor
  BouncingBall(float _locationX, float _locationY, float _xSpeed, float _ySpeed, int _diameter) {

    // 把临时变量赋值给变量
    locationX = _locationX;
    locationY = _locationY;
    xSpeed = _xSpeed;
    ySpeed = _ySpeed;
    diameter = _diameter;
  }

  // 方法 method
  void move() {
    // Change the x location by speed
    locationX += xSpeed;
    locationY += ySpeed;


    // If we’ve reached an edge, reverse speed
    if ((locationX > width-diameter/2) || (locationX < 0+diameter/2)) {
      xSpeed *= -1;
    }

    if ((locationY >= height-diameter/2) || (locationY <= 0+diameter/2)) {
      ySpeed *= -1;
    }
  }

  void display() {
    stroke(0);
    fill(175);
    ellipse(locationX, locationY, diameter, diameter);
  }
}

类的定义和取名

首先 class 小写,类名应含有大写或全部大写,这之前讲过。

class BouncingBall{

}

用大括弧{}给出程序块的空间。

类的变量声明

float locationX; // 位置
float locationY;
float xSpeed; // 速度
float ySpeed;
int diameter; // 大小

类所独用的变量,同时也可以作为实例的方法,在主程序中被调用。

print(jsj.locationX);

这点很重要,因为 OOP 的目的就是让数据可以在不同的模块中流通,这个模块就是类。

类的构建

我们把构建 constructor 理解为是类的接口,设置形参 parameter, 用于在实例初始化的时候可输入具体的实参 arguments,给变量赋值。

// 构建 constructor
BouncingBall(float _locationX, float _locationY, float _xSpeed, float _ySpeed, int _diameter) {

  // 把临时变量赋值给变量
  locationX = _locationX;
  locationY = _locationY;
  xSpeed = _xSpeed;
  ySpeed = _ySpeed;
  diameter = _diameter;
}

类的方法

和自定义函数的语法类似,如果只要求方法执行,不回报值的情况下,用 void 打头

void move(){


}
void display(){

}

总结

实例导向,可以让你通过类创建不同的实例,并且赋予不同的实例以特征,和函数一样可被重复调用和优化。OOP 是一种写代码的思路和理解系统和看待世界的方式。