Questions about extending PVector class

edited July 2017 in Questions about Code

Having a hard time figuring out when and why this should be done. And if I don't need to do it, how do I update older code to not use it?

Here is an example.

How would this class be rewritten to avoid using PVector inheritance?

class Bullet extends PVector {
  PVector vel;

  Bullet(PVector loc, PVector vel) {
    super(loc.x, loc.y);
    this.vel = vel.get();
  }

  void update() {
    add(vel);
  }

  void display() {
    fill(0, 0, 255);
    ellipse(x, y, 3, 3);
  }
}

Answers

  • Is this homework?

    Technically, you think of a bullet to be a vector that contains another vector. Based on the constructor you provided, you can see that the first field is location which is assigned to itself using the super() function. So, base on this information and the current layout of your code, this could be rewritten as:

    class Bullet  {
    float locx,locy;
    float vx,vy;
    
      Bullet(float x1, float y1, float x2, float y2) {
        locx=x1;
        locy=y1;
        vx=x2;
        vy=y2;
      }
    
      void update() {
        locx+=vx;
        locy+=vy;
      }
    
      void display() {
        fill(0, 0, 255);
        ellipse(locx, locy, 3, 3);
      }
    }
    

    Kf

  • edited July 2017

    Thanks for that. Not for homework, but we have never talked about extending PVector in class and I see it in examples here quite often.

    If I'm not mistaken, your code could be written like:

        class Bullet {
          PVector vel, loc;
    
          Bullet(PVector loc_, PVector vel_) {
            loc = loc_;
            vel = vel_;
          }
    
          void update() {
            loc.add(vel);
          }
    
          void display() {
            fill(0, 0, 255);
            ellipse(loc.x, loc.y, 3, 3);
          }
        }
    

    but this doesn't work in the example on that page, so I'm wondering what sorcery I'm missing.

  • Answer ✓
        loc = loc_.copy();
        vel = vel_.copy();
    

    Kf

  • THANK YOU! So back to my original question, is there a preference as to whch way to do this? Am I just being taught a more newb-friendly way?

  • edited July 2017 Answer ✓

    That was merely a "hack" for typing in loc.add(vel); as just add(vel); and loc.x as simply x. :ar!
    The only problem w/ such approach is for when exporting it to the web via Pjs. :|
    B/c we can't use extends for Processing's own classes in Pjs, but ours only. :-@

  • Answer ✓

    Here's an alternative version using point() + strokeWeight() + pushStyle() btW: :-bd

    // Forum.Processing.org/two/discussion/23575/
    // questions-about-extending-pvector-class#Item_6
    
    // GoToLoop (2017-Jul-25)
    
    class Bullet {
      static final color COLOUR = #0000FF;
      static final short DIAM = 3;
    
      final PVector loc, vel;
    
      Bullet(PVector pos, PVector spd) {
        loc = pos.get();
        vel = spd.get();
      }
    
      void update() {
        loc.add(vel);
      }
    
      void display() {
        pushStyle();
        stroke(COLOUR);
        strokeWeight(DIAM);
        point(loc.x, loc.y);
        popStyle();
      }
    }
    
  • Answer ✓

    Is there a preference? I think if it works, it is good. At the end, it is part of your design. If you have an object that its intrinsic and core functionality are solely described by a PVector class, then there is nothing wrong with extending this class. When it comes to design, I make an effort of seeing the big picture. Do I have to do that? Should it be like that? Can it be done differently? What trade offs do I get and are they meaningful? Can this approach make maintenance easier?

    For small projects, either approach is more based on taste in my opinion.

    Kf

  • Thanks both, really appreciate this!

  • edited July 2017 Answer ✓

    Yes there is a preference, actually not just a preference but a correct way to do it. :)

    1) Inheritance.
    Inheritance represents a kind of relationship between classes so ...

    class Bullet extends PVector {
    }
    

    suggests that Bullet is a kind of PVector --- WRONG!

    2) Aggregation / Composition
    When describing a Bullet object we need to consider what information we need to know about it e.g. position, velocity, acceleration, weight ... These describe some aspect of a Bullet so we say that a Bullet is an aggregation of position, velocity etc.

    class Bullet {
      PVector pos;
      PVector velocity;
      PVector accel;
      float weight;
      ...
    }
    

    suggests that Bullet is composed of position, velocity etc. --- CORRECT

    NOTE: pos, velocity ... are called fields or attributes (I prefer attributes because it is more accurately describes what they represent)

    It might seem a small thing because it is possible to write software using inheritance or aggregation for the relationship between Bullet and PVector, but if you pick the wrong one (i.e. inheritance) you will end up writing crap code to overcome the invalid relationship.

  • Thanks quark... good way to think about it.

Sign In or Register to comment.