In this question and this post is explained how to clone objects with final fields by using protected copy constructors.
However, supposing that we have:
public abstract class Person implements Cloneable
{
private final Brain brain; // brain is final since I do not want
// any transplant on it once created!
private int age;
public Person(Brain aBrain, int theAge)
{
brain = aBrain;
age = theAge;
}
protected Person(Person another)
{
Brain refBrain = null;
try
{
refBrain = (Brain) another.brain.clone();
// You can set the brain in the constructor
}
catch(CloneNotSupportedException e) {}
brain = refBrain;
age = another.age;
}
public String toString()
{
return "This is person with " + brain;
// Not meant to sound rude as it reads!
}
public Object clone()
{
return new Person(this);
}
public abstract void Think(); //!!!!
…
}
Returns an error since we can't instantiate an abstract class. How can we solve this?
You don't implement the clone() method in the abstract class, only in the concrete sub-classes.
public class SomeConcretePerson extends Person
{
public SomeConcretePerson (SomeConcretePerson another)
{
super (another); // this will invoke Person's copy constructor
}
public Object clone()
{
return new SomeConcretePerson(this);
}
}
In some rare cases, we might not be able to use the copy constructor technique and have to use the clone() method. For these cases, it’s worth knowing that Java offers a work-around for the final field problem:
public abstract class Person implements Cloneable {
private final Brain brain;
private int age;
public Person(Brain aBrain, int theAge) {
brain = aBrain;
age = theAge;
}
#Override public String toString() {
return "This is person with " + brain;
// Not meant to sound rude as it reads!
}
#Override public Person clone() {
try {
Person clone = (Person)super.clone();
Field brainField=Person.class.getDeclaredField("brain");
brainField.setAccessible(true);
brainField.set(clone, brain.clone());
return clone;
} catch (CloneNotSupportedException|ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
public abstract void think();
…
}
The possibility to override the final restriction was created for exactly such use cases, cloning or deserializing an object, where no constructor will be called. The Java Language Specification, §17.5.3. Subsequent Modification of final Fields states:
In some cases, such as deserialization, the system will need to change the final fields of an object after construction. final fields can be changed via reflection and other implementation-dependent means. The only pattern in which this has reasonable semantics is one in which an object is constructed and then the final fields of the object are updated. The object should not be made visible to other threads, nor should the final fields be read, until all updates to the final fields of the object are complete.
This is exactly how the example works, setting the final field right after the clone’s construction, before the clone is exposed to anyone, and not reading any field.
As said, cases in which this is required, are rare. As long as you can implement a copy constructor based solution, use that.
If you just want a new instance of the class without cloning the values of its members then you can use the following:
public static < T > T getNewInstance ( Class <T> type )
{
try
{
return type.newInstance() ;
} catch ( InstantiationException | IllegalAccessException e)
{
e.printStackTrace();
}
return null ;
}
For deep cloning of objects you can use com.rits.cloning.Cloner utility. For eg. :
private T clone(T resource){
Cloner cloner = new Cloner();
T cloneObject = (T) cloner.deepClone(obj);
return cloneObject;
}
We can't instantiate an abstract class but we can do it in the subClass
class Teacher extends Person {
public Teacher(Brain aBrain, int theAge) {
super(aBrain, theAge);
}
protected Teacher(Person another) {
super(another);
}
public Object clone() {
return new Teacher(this);
}
}
Related
I'm attempting to create a copy method, but what I have seems too simple and I think it's essentially doing nothing.
public Validation copy(Validation newValidation){return newValidation;}
so if implemented like so:
Validation x = new Validation();
Validation y = x.copy(x);
And then make sure that y has all the methods/variables of x and that when working with the variables in y, I don't affect the variables in x. I have a feeling what I want is a "deep copy" method and I found a post about it here: Creating a deep copy method, Java but that person has no argument for their method so I don't know how it is actually copying.
Yes, it does nothing except returning the same reference that has been passed.
Probably, you are looking for the Object#clone()* method:
public Validation copy(Validation newValidation) {
return newValidation.clone();
}
In 95% cases, that is the most appropriate and proper solution for different types of tasks. You should not reinvent the wheel if there isn't a need of it.
As the Java documentation says:
... this method performs a "shallow copy" of this object, not a "deep copy" operation.
... it may be necessary to modify one or more fields of the object returned by super.clone before returning it.
Validation y = x.copy(x);
You shouldn't pass an x to a copy method because when you are calling this method on an x instance, inside the class you have an access to this which, in this case, represents your x.
Validation y = x.clone();
For a "shallow copy" the preceding example is good, but for a "deep copy" you need to override a default Object#clone() behaviour:
class A implements Cloneable {
public #Override A clone() throws CloneNotSupportedException {
return (A)super.clone(); // or or another implementation
}
}
class Validation implements Cloneable {
// an example of a reference-type field
private A a; // with a setter
public #Override Validation clone() throws CloneNotSupportedException {
Validation newClone = new Validation();
// note that the `A` class has to implement the `Cloneable`
// and override the `clone` method making it `public`
newClone.setA(this.a.clone());
return newClone;
}
}
*Don't forget to implement the Cloneable interface to allow cloning.
To read: Effective Java, Item 11: Override clone judiciously.
The Java api has a Cloneable Interface.Object has a clone method that can only be accessed when it's overridden in the subclass, that also implements the Cloneable interface. Your method does not really create a copy, since the "copy" points to the original instance.
Let's say I make a copy of Validation :
Validation v = new Validation();
v.setId(1);
Validation valid = v.copy(v);
valid.setId(2);
Now the id in v will change as well, because valid points to v.
But the clone-Method makes a deep-copy. Here is a small example :
public class Product {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Product{" + "id=" + id + ", name=" + name + '}';
}
#Override
protected Object clone() throws CloneNotSupportedException {
Product p = new Product();
p.setId(id);
p.setName(name);
return p;
}
}
public static void main(String[] args) {
Product p = new Product();
try {
Product clone = (Product) p.clone();
System.out.println(clone.toString());
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
I'm working with the Java AWS API to monitor some EC2 instances and on every refresh I need to query the service which returns a bunch of Instance objects (freshly constructed). I want to extend the functionality of these objects, I figure I can maintain a map of MyInstance objects which can be refreshed with the new Instances on each poll.
Now I could easily do this with a simple wrapper class that holds the original Instance as a property the issue is I would like to keep access to the base Instance API as I already use these functions in my code. Would it be possible to replace only the super-class parts of an instantiated object? Contrived example of what I'm going for:
class Instance {
protected int prop;
public Instance(int prop) {
this.prop = prop;
}
}
class MyInstance extends Instance {
protected int prop2;
public MyInstance(int prop, int prop2) {
super(prop);
this.prop2 = prop2;
}
}
MyInstance foo = new MyInstance(1, 2);
Instance foster = new Instance(3);
//what i want to do
foo.adoptedBy(foster);
//with the result that foo.prop == 3
Obviously this example would be trivial to transform but in my actual case there are far more properties that need to be transferred. Can Reflection do this? What kind of performance impact am I looking at if I use Reflection for 10 of these every second? Thanks for reading!
The best solution is to combine both your ideas:
Wrap the original Instance in a class that extends the Instance class. (In the constructor of the child class, you can create a new Instance object and set it)
Delegate all methods to the wrapped instance (and add new properties)
In your foster method, you simply change the wrapped Instance.
class Instance {
private int prop;
public Instance(int prop) {
this.prop = prop;
}
public int getProp() {
return prop;
}
}
class MyInstance extends Instance {
private Instance delegate;
private int prop2;
public MyInstance(Instance delegate, int prop2) {
super(prop);
this.delegate = delegate;
this.prop2 = prop2;
}
#Override
public int getProp() {
return delegate.getProp();
}
public int getProp2() {
return prop2;
}
public void foster(Instance i) {
delegate = i;
}
}
MyInstance foo = new MyInstance(1, 2);
Instance foster = new Instance(3);
//what i want to do
foo.adoptedBy(foster);
//with the result that foo.getProp() == 3
I have a base class say
class A {
private String name;
private String age;
//setters and getters for same
}
and a child class say
class B extends A {
private String phone;
private String address;
//setters and getters for same
}
now I've an instance of A and besides this I have to set the fields in B as well, so code would be like,
A instanceOfA = gotAFromSomewhere();
B instanceOfB = constructBFrom(instanceOfA);
instanceOfB.setPhone(getPhoneFromSomewhere());
instanceOfB.setAddress(getAddressFromSomewhere());
can I instantiate B with given A, but I don't want to do this way,
B constructBFrom(A instanceOfA) {
final B instanceOfB = new B();
instanceOfB.setName(instanceOfA.getName());
instanceOfB.setPhone(instanceOfA.getAge());
return B;
}
rather what I'd love to have some utility with function which is generic enough to construct object as in,
public class SomeUtility {
public static <T1, T2> T2 constructFrom(T1 instanceOfT1, Class<T2> className) {
T2 instatnceOfT2 = null;
try {
instatnceOfT2 = className.newInstance();
/*
* Identifies the fields in instanceOfT1 which has same name in T2
* and sets only these fields and leaves the other fields as it is.
*/
} catch (InstantiationException | IllegalAccessException e) {
// handle exception
}
return instatnceOfT2;
}
}
so that I can use it as,
B constructBFrom(A instanceOfA) {
return SomeUtility.constructFrom(instanceOfA, B.class);
}
Moreover, use case will not be only limited to parent-child classes, rather this utility function can be used for adapter use cases.
PS- A and B are third party classes I've to use these classes only so I can't do any modifications
in A and B.
The good practice is to have a factory class which "produces" the instances of B.
public class BFactory {
public B createBFromA(A a) { ... }
}
You have to write the code of the factory method as there is no standard way of creating a child class based on its parent class. It's always specific and depends on the logic of your classes.
However, consider if it is really what you need. There are not many smart use cases for instantiating a class based on the instance of its parent. One good example is ArrayList(Collection c) - constructs a specific list ("child") containing the elements of the generic collection ("base").
Actually, for many situation there is a pattern to avoid such strange constructs. I am aware it's probably not applicable to your specific case as you wrote that your Base and Child are 3rd party classes. However your question title was generic enough so I think you may find the following useful.
Create an interface IBase
Let the class Base implement the interface
Use composition instead of inheritance - let Child use Base instead of inheriting it
Let Child implement IBase and delegate all the methods from IBase to the instance of Base
Your code will look like this:
public interface IBase {
String getName();
int getAge();
}
public class Base implements IBase {
private String name;
private int age;
// getters implementing IBase
}
public class Child implements IBase {
// composition:
final private IBase base;
public Child(IBase base) {
this.base = base;
}
// delegation:
public String getName() {
return base.getName();
}
public int getAge() {
return base.getAge();
}
}
After you edited your question, I doubt even stronger that what you want is good. Your question looks more like an attempt of a hack, of violating (or not understanding) the principles of class-based object oriented concept. Sounds to me like someone coming from the JavaScript word and trying to keep the JavaScript programming style and just use a different syntax of Java, instead of adopting a different language philosophy.
Fun-fact: Instantiating a child object with parent object is possible in prototype-based languages, see the example in JavaScript 1.8.5:
var base = {one: 1, two: 2};
var child = Object.create(base);
child.three = 3;
child.one; // 1
child.two; // 2
child.three; // 3
In my opinion the way you want to avoid is very appropriate. There must be a piece of such code somewhere.
If you can't put that method in the target class just put it somewhere else (some factory). You should additionaly make your method static.
Take a look at Factory method pattern.
2nd option would be extending B and place this method as factory static method in that new class. But this solution seems to be more complicated for me. Then you could call NewB.fromA(A). You should be able then use your NewB instead of B then.
You could do it via reflection:
public static void copyFields(Object source, Object target) {
Field[] fieldsSource = source.getClass().getFields();
Field[] fieldsTarget = target.getClass().getFields();
for (Field fieldTarget : fieldsTarget)
{
for (Field fieldSource : fieldsSource)
{
if (fieldTarget.getName().equals(fieldSource.getName()))
{
try
{
fieldTarget.set(target, fieldSource.get(source));
}
catch (SecurityException e)
{
}
catch (IllegalArgumentException e)
{
}
catch (IllegalAccessException e)
{
}
break;
}
}
}
}
*Above code copied from online tutorial
I'd like to extend ArrayList to add a few methods for a specific class whose instances would be held by the extended ArrayList. A simplified illustrative code sample is below.
This seems sensible to me, but I'm very new to Java and I see other questions which discourage extending ArrayList, for example Extending ArrayList and Creating new methods. I don't know enough Java to understand the objections.
In my prior attempt, I ending up creating a number of methods in ThingContainer that were essentially pass-throughs to ArrayList, so extending seemed easier.
Is there a better way to do what I'm trying to do? If so, how should it be implemented?
import java.util.*;
class Thing {
public String name;
public int amt;
public Thing(String name, int amt) {
this.name = name;
this.amt = amt;
}
public String toString() {
return String.format("%s: %d", name, amt);
}
public int getAmt() {
return amt;
}
}
class ThingContainer extends ArrayList<Thing> {
public void report() {
for(int i=0; i < size(); i++) {
System.out.println(get(i));
}
}
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
public class Tester {
public static void main(String[] args) {
ThingContainer blue = new ThingContainer();
Thing a = new Thing("A", 2);
Thing b = new Thing("B", 4);
blue.add(a);
blue.add(b);
blue.report();
System.out.println(blue.total());
for (Thing tc: blue) {
System.out.println(tc);
}
}
}
Nothing in that answer discourages extending ArrayList; there was a syntax issue. Class extension exists so we may re-use code.
The normal objections to extending a class is the "favor composition over inheritance" discussion. Extension isn't always the preferred mechanism, but it depends on what you're actually doing.
Edit for composition example as requested.
public class ThingContainer implements List<Thing> { // Or Collection based on your needs.
List<Thing> things;
public boolean add(Thing thing) { things.add(thing); }
public void clear() { things.clear(); }
public Iterator<Thing> iterator() { things.iterator(); }
// Etc., and create the list in the constructor
}
You wouldn't necessarily need to expose a full list interface, just collection, or none at all. Exposing none of the functionality greatly reduces the general usefulness, though.
In Groovy you can just use the #Delegate annotation to build the methods automagically. Java can use Project Lombok's #Delegate annotation to do the same thing. I'm not sure how Lombok would expose the interface, or if it does.
I'm with glowcoder, I don't see anything fundamentally wrong with extension in this case--it's really a matter of which solution fits the problem better.
Edit for details regarding how inheritance can violate encapsulation
See Bloch's Effective Java, Item 16 for more details.
If a subclass relies on superclass behavior, and the superclass's behavior changes, the subclass may break. If we don't control the superclass, this can be bad.
Here's a concrete example, lifted from the book (sorry Josh!), in pseudo-code, and heavily paraphrased (all errors are mine).
class CountingHashSet extends HashSet {
private int count = 0;
boolean add(Object o) {
count++;
return super.add(o);
}
boolean addAll(Collection c) {
count += c.size();
return super.addAll(c);
}
int getCount() { return count; }
}
Then we use it:
s = new CountingHashSet();
s.addAll(Arrays.asList("bar", "baz", "plugh");
And it returns... three? Nope. Six. Why?
HashSet.addAll() is implemented on HashSet.add(), but that's an internal implementation detail. Our subclass addAll() adds three, calls super.addAll(), which invokes add(), which also increments count.
We could remove the subclass's addAll(), but now we're relying on superclass implementation details, which could change. We could modify our addAll() to iterate and call add() on each element, but now we're reimplementing superclass behavior, which defeats the purpose, and might not always be possible, if superclass behavior depends on access to private members.
Or a superclass might implement a new method that our subclass doesn't, meaning a user of our class could unintentionally bypass intended behavior by directly calling the superclass method, so we have to track the superclass API to determine when, and if, the subclass should change.
I don't think extending arrayList is necessary.
public class ThingContainer {
private ArrayList<Thing> myThings;
public ThingContainer(){
myThings = new ArrayList<Thing>();
}
public void doSomething(){
//code
}
public Iterator<Thing> getIter(){
return myThings.iterator();
}
}
You should just wrap ArrayList in your ThingContainer class. ThingContainer can then have any processing methods you need. No need to extend ArrayList; just keep a private member.
Hope this helps.
You may also want to consider creating an interface that represents your Thing Class. This gives you more flexibility for extensibility.
public Interface ThingInterface {
public void doThing();
}
...
public OneThing implements ThingInterface {
public void doThing(){
//code
}
}
public TwoThing implements ThingInterface {
private String name;
public void doThing(){
//code
}
}
Here is my suggestion:
interface ThingStorage extends List<Thing> {
public int total();
}
class ThingContainer implements ThingStorage {
private List<Thing> things = new ArrayList<Thing>();
public boolean add(Thing e) {
return things.add(e);
}
... remove/size/... etc
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
And report() is not needed actually. toString() can do the rest.
public class Atribut {
int classid;
#Override public String toString() {
return Integer.toString(classid);
}
}
I have made this class which overrides method toString(). I plan on making many subclasses with different classid. The problem is I dont know how to set the variable classid to work in toString method.
public class cas extends Atribut{
int classid=2;
}
The problem is if I make an cas object and toString method it returns "0" not "2".??
My preferred technique for this kind of thing is to use constructor arguments:
public class Parent {
// Using "protected final" so child classes can read, but not change it
// Adjust as needed if that's not what you intended
protected final int classid;
// Protected constructor: must be called by subclasses
protected Parent(int classid) {
this.classid = classid;
}
#Override
public String toString() {
return Integer.toString(classid);
}
}
public class Child extends Parent {
public Child() {
// The compiler will enforce that the child class MUST provide this value
super(2);
}
}
Much as #java_mouse recommended, just use the parent class's variable.
public class Atribut {
protected int classid;
public Atribut() {
classid = 0;
}
#Override
public String toString() {
return Integer.toString(classid);
}
}
public class Cas extends Atribut{
public Cas() {
classid = 2;
}
}
Set classid's value in the constructor and then you can use the superclass's toString() just fine.
When you shadow the variable, the one in the parent class is used in methods there.
If you want to do this, I would do this
class Atribut {
int classid = 0;
protected int classid() { return classid; } // points to Attribut.classid
public String toString() {
return Integer.toString(classid());
}
}
Then in your child class, you can override the method
class cas {
int classid = 2;
protected int classid() { return classid; } // points to cas.classid
}
Why do you want to shadow a variable in child class if it is already available in the parent? why not using the same variable?
if you use the same variable, the issue is resolved automatically. Don't duplicate the attribute if it has to be inherited.
I think most of the answers here narrow down to style preference.
For such small examples, most of the provided solutions would work just fine.
However, let's assume that you have an inheritance tree that is several levels deep. In such a scenario, it might be challenging to understand the source of each property, so using setters, getters, and references to the superclass might come in handy. My personal choice would be as follows:
public class Atribut {
private int firstProp;
private int thirdProp;
public int getFirstProp() {
return firstProp;
}
public void setFirstProp(int firstProp) {
this.firstProp = firstProp;
}
....
#Override
public String toString() {
return Integer.toString(this.getFirstProp()) +
Integer.toString(this.getThirdProp());
}
}
public class Cas extends Atribut {
private int secondProp;
public Cas() {
super.setFirstProp(1);
this.setSecondProp(2);
super.setThirdProp(3);
}
}
An alternative implementation, using the approaches provided above would result in the this Cas class:
public Cas() {
super(1, 3)
secondProp = 2;
}
This second solution is a bit harder to read and is less descriptive about what properties are you setting.
For those reasons, that is the style that I prefer. Also, to reiterate, the benefits of the first approach become more evident for more complex examples.