How to implement repetitive behavior when inheritance is not an option

I have two classes that have some properties and behavior. One of these clusters of general behavior is manipulation in three-dimensional space. Thus, each implements an interface Transformable:

public interface Transformable {

    public void position (double x, double y, double z);
    public void position (Tuple3d tuple);

    public void rotateDeg (double yaw, double pitch, double roll);
    public void rotateRad (double yaw, double pitch, double roll);

    // And so on...

}

public class Foo extends Apple  implements Transformable { // Foo happens }
public class Bar extends Orange implements Transformable { // Bar happens }

Now the behavior for each method in is Transformableidentical for any implementation class, and the necessary code is essential.

Fooand Bareach of them extends various superclasses that I do not control, and Java does not have multiple inheritance, so the option is missing.

Copying and pasting a piece of code into each class that implements Transformableis contrary to all things programming.

, , :

public Foo extends Apple implements Transformable {

    // This class has all of the repeated implementation code
    private TransformationHelper helper;

    public final void rotate (double yaw, double pitch, double roll) {
        helper.rotate(yaw, pitch, roll);
    }
}

, . , .

- ?

: , Transformable. : Foo Bar . Shoe SpaceShuttle, 3D- .position(x,y,z), .

+4
4

Java. .

@Naruto_Biju_Mode , Java 8, Transformable, , - ,

 interface Transformable {



    default void rotate (double yaw, double pitch, double roll) {
        TransformationHelper.rotate(yaw, pitch, roll);
    }

     ...
   }

- . ,

interface Transformable {



    default void rotate (double yaw, double pitch, double roll) {
       //actual implementation without helper class
    }

     ...
   }

, , ,

+3

, : Iterator/Iterable. Iterator , .

Transformable :

interface Transformable {
   Transformer getTransformer();
}

, Foo, Foo, foo.getTransformer() Transformer, .

Transformer , , .

+4

(FYI Considering deleting my post as a header, says: "Inheritance is not an option")

You basically create an abstract superclass, say AbstractFruitfor which you can still chooseTransformable

public abstract class AbstractFruit implements Transformable {
  @Override
  public void position (double x, double y, double z) {
    // provide implementation
  } 
  @Override
  public final void rotate (double yaw, double pitch, double roll) {
    // provide implementation
  }    
}

You can then add your fruit to this abstract superclass.

0
source
public interface Transformable {

public void position (double x, double y, double z);
public void position (Tuple3d tuple);

public void rotateDeg (double yaw, double pitch, double roll);
public void rotateRad (double yaw, double pitch, double roll);

// And so on...

}

public class ConcreteTransformable implements Transformable {

//implement a concrete class here, you can even put your helper methods in here

 public void position (double x, double y, double z) {

 } 

 public void position (Tuple3d tuple) {

 }

 public void rotateDeg (double yaw, double pitch, double roll) {

 };

 public void rotateRad (double yaw, double pitch, double roll) {

 };

}

public Foo extends Apple implements Transformable {

private Transformable transform = new ConcreteTransformable();

 //if your orange needs another transform than the standard, just pass the transformable via constructor
 public Apple(Transformable transform) {
     this.transform = transform;
 }

 public void position (double x, double y, double z) {
      transform.position(x,y,z);
 } 

 public void position (Tuple3d tuple) {
      transform.position(tuple);
 }

 //other methods also delegate to the transformable

}

-2
source

All Articles