Problema con Class, extend y herencia

I didn’t need to translate anything, nor use Google Translate. :wink:

Like I had already explained, you’re gonna need to implement clone() in your own class, rather than relying on the new operator:

So instead of:

Ball hijo() {
  return new Ball();
}

Go w/ something like this:

Ball hijo() {
  return clone();
}

@Override Ball clone() {
  try {
    final Ball hijo = (Ball) super.clone();
    hijo.location = location.get();
    return hijo;
  }
  catch (final CloneNotSupportedException e) {
    throw new RuntimeException(e);
  }
}

Notice I had to do: hijo.location = location.get();. Here’s the reason why: :warning:

  • Your class Ball got 2 fields: location & nombre.
  • The 1st refers to a PVector, while the 2nd refers to a String.
  • Datatype String is immutable. Its content can’t be changed (at least not w/o some hardcore hacking :smiling_imp:).
  • However, datatype PVector is mutable. Its fields x, y & z can be freely reassigned.
  • If we don’t also clone each mutable field from a class when we call clone(), modifying those mutable fields will reflect on both the original object and all of its clones! :fearful:
  • That’s why I invoke the method PVector::get() over the cloned field location, so the original and the cloned field location won’t share the same PVector object: :nerd_face:
  • ProcessingJS.org/reference/PVector_get_/

Below’s my new attempt sketch “Cloneable Locatable”. Any doubts about it just ask: :innocent:

/**
 * Cloneable Locatable (v1.0.1)
 * GoToLoop (2019/May/14)
 * Discourse.Processing.org/t/problema-con-class-extend-y-herencia/11204/4
 */

import org.gicentre.utils.geom.HashGrid;
import org.gicentre.utils.geom.Locatable;

import java.util.Collection;
//import java.util.Set;

static final int SIZE = 10;
final Collection<Bola> temp = new ArrayList<Bola>();

Collection<Bola> pelotas;
//Set<Bola> pelotas;
//HashGrid<Bola> pelotas;

void setup() {
  size(400, 400);
  noLoop();

  pelotas = new HashGrid<Bola>(width, height, SIZE);

  pelotas.add(new Bola());
  pelotas.add(new Bolita());
}

void draw() {
  background((color) random(#000000));
  getSurface().setTitle("Frame: " + frameCount);
  println("\nPelotas: " + pelotas.size());
  for (final Bola b : pelotas)  println(b);
}

void mousePressed() {
  temp.clear();
  for (final Bola b : pelotas)  temp.add(b.hijo());
  pelotas.addAll(temp);
  redraw = true;
}

class Bola implements Locatable, Cloneable {
  PVector location = new PVector(40, 20);
  String nombre = getClass().getSimpleName();

  Bola hijo() {
    return clone();
  }

  @Override Bola clone() {
    try {
      final Bola pelota = (Bola) super.clone();
      pelota.location = location.get();
      return pelota;
    }
    catch (final CloneNotSupportedException e) {
      throw new RuntimeException(e);
    }
  }

  @Override PVector getLocation() {
    return location;
  }

  @Override String toString() {
    return nombre + ": " + location;
  }
}

class Bolita extends Bola {
}
1 Like