1

I am new to Java and Object-Orientation so apologies if I am not clear.

I have made an Aquarium using Env3D and want to apply the principles of SOLID

I have a Simulation class, Token class, Fish Class's.

My Token class currently deals with generating the fish and their behavior. Idealistically I want the behavior to be a separate class from the Token class.

I would need my Fish to extend two classes, Token and Behavior which I know isn't possible.

How would I do this? The Fish could implement a Behavior interface but how would it get the fields and methods from the Behavior class?

Token Class

package UserCode;

/**
* It's a Token!
* 
* @author (Tom) 
* @version (02.03.2017)
*/
public class Token
{

// Env3d-defined object-specific fields:
// Reference to the 3D model, called 'model':
String model;

// Reference to texture-map, called 'texture':
String texture;

// Scale factor applied to model:
double scale;

// Position in 3D world (x,y,z coordinates):
double x;

// Position in 3D world (x,y,z coordinates):
double y;

// Position in 3D world (x,y,z coordinates):
double z;

// Orientation (about x,y,z):
double rotateX;

// Orientation (about x,y,z):
double rotateY;

// Orientation (about x,y,z):
double rotateZ;

// Set transparency to true:
boolean transparent=true;


public void setModel(String model){
   this.model = model;
}

public void setScale(double scale){
   this.scale = scale;
}

public void setTexture(String texture){
   this.texture = texture;
}

public void move()
{
    // rotate about y axis
    //rotateY += 1;
}



public void setOrientationX(double x)
{
    // set position
    this.rotateX = x;
}

public void setOrientationY(double y)
{
    // set position
    this.rotateY = y;
}

public void setOrientationZ(double z)
{
    // set position
    this.rotateZ = z;
}





public void setPositionX(double x)
{
    // set position
    this.x = x;
}

public void setPositionY(double y)
{
    // set position
    this.y = y;
}

public void setPositionZ(double z)
{
    // set position
    this.z = z;
}
}

JavaFish Class

package UserCode;

/**
* <h1>Aquarium: JavaFish</h1>
* <p>This class generates and controls the JavaFish in the Aquarium.
* <p>The characteristics of the JavaFish are to swim horizontelly, backwards    and forwards.
* 
*@version 1.0.0
*@author Tom
*/

public class JavaFish extends Token
{
private double _xspeed = 0.08;

/**
 * Creates the JavaFish and initilises instance/object variables of images of JavaFish and Aquarium.
 * The second initilises position and orientation. These come from the     Framework package.
 */

public JavaFish()
{
    setModel("models/billboard/billboard.obj");
    setScale(0.5);
    setTexture("textures/javaFish/JavaFish.png");


    setPositionX(1.0);
    setPositionY(5.0);
    setPositionZ(1.0);

    setOrientationX(0);
    setOrientationY(-90);
    setOrientationZ(0);
}

public void move()
{
    // JavaFish x-axis assigned to move forwards (+=) by instance varible in constructor
    x += _xspeed;

    // Flip JavaFish orientation and change direction if fish reaches specific x-axis point
    if (x < 2)
    {
       _xspeed = 0.05;
        setOrientationY(-90);
    } else if (x > 8){
        _xspeed = -0.05;
        setOrientationY(90);
    } 
}
}
moondaisy
  • 4,303
  • 6
  • 41
  • 70
  • Assuming that `Behavior` defines the behavior of the fish (e.g. how it moves), the logical approach would be to leave `Behavior` as a separate class and have a method like `setBehavior` in `Fish`. See [Visitor-pattern](https://en.wikipedia.org/wiki/Visitor_pattern). Hard to tell though without seeing the actual code of `Behavior`. –  Mar 13 '17 at 20:55
  • "My Token class currently deals with generating the fish and their behavior" if this is your goal then I don't see why `Fish` should extend any of these classes. The behavior could compose the fish class (as a class variable) and `Token` should create each `Fish` and pass it it's corresponding behavior. – moondaisy Mar 13 '17 at 20:55

2 Answers2

0

Have Token extend Behavior, then have Fish extend Token, so your Fish class will inherit objects from both Token and Behavior.This is the best way to get around the multiple inheritance problem in your situation.

As an alternative, your Token class looks to be just variable declarations and their respective getters and setters, so it probably wouldn't be to much of a pain to make Token an interface.

ack
  • 1,181
  • 1
  • 17
  • 36
0

To achieve the design of your solution you should consider "composition over inheritance" principle (see wikipedia for code examples).

If i'm understanding your problem, Fish is a Token, i agree. However Fish is not a Behaviour, Fish has a behaviour. Then you should aggregate Behaviour object as Token attribute, calling methods from it, etc.

You can also add another level of abstraction by defining Behaviour as interface, implemented by concrete classes (let's say Behaviour1, Behaviour2). Behaviour objects can be accessed by Token class using an additional abstract getBehaviour() method in Token class, overriden in Fish class by method returning Behaviour1 or Behaviour2 implementations.

Benjamin Caure
  • 2,090
  • 20
  • 27