Search code examples
javaclonecloning

Java - cloning through extending


Imagine situation:

I have got two classes

public class Fruit{
}

and:

 public class FruitOnSale extends Fruit{
     int price;
     public int getPrice() or something
 }

My program has one fruit and one fruitOnSale object. I would like to create completly new (clone) fruit2 [Fruit] based on the fruitOnSale (for example somebody has bought fruitOnSale and it needs to appear in his bag but as a normal fruit cause it is no more in shop). The method getPrice and field price are deleted during it. Then backwards - somebody creates a shop (...) and puts his fruit on sale. Now I need to convert fruit to FruitOnSale (I want it to be in the shop as 'on sale' and in my bag as 'normal', but as independent objects).

These classes will be rebuilded, modified and lots work may be done on them, so I don't want to manualy rewrite them just by copying every field because it's sensless. Is it possible through clonning? Or have you got better ideas?


Solution

  • Use composition:

    public class Fruit {
       // your regular fruit class
    }
    

    Your "fruit on sale":

    public class FruitOnSale {
    
        private Fruit fruit;     
        private int price;
    
        public FruitOnSale(Fruit fruit, int price) {
            this.fruit = new Fruit(fruit.getName());
            this.price = price;
        }
    
        public Fruit getFruit() {
            return Fruit(fruit.getName());
        }
    }
    

    Now you can construct FruitOnSale instances by passing in a Fruit instance, and you can get a Fruit instance from FruitOnSale instance as well. Notice that when you initialize a FruitOnSale instance with a Fruit instance, it creates a "copy" of the Fruit instance. It's good to do this, otherwise you could modify the original Fruit instance, which would then affect the FruitOnSale instance. This is not what you want, if you are assuming that these are immutable. Similarly, getFruit() doesn't return a reference to the internal instance, but creates an entirely-new Fruit instance as well.

    While solving this particular example using inheritance does not violate the Liskov Substitution Principle, in general it is a good idea to think about the impact of extending the base class. For example, there might be some things that you can do with Fruit, that don't make sense with FruitOnSale (i.e., could lead to inconsistent, illogical, or unpredictable behavior); this would be an example of LSP being violated.