4

I have a very simple question.

Can 2 classes share the same Super class instance? I know the answer is no, because super is the instance itself, but I was really there was some workaround...

public class Parent{
    private final int parentId;
    private static final HashMap<Integer,Parent> parentMap = new HashMap<Integer,Parent>();

    private Parent(int i){
       parentId = i;
       parentMap.put(i,this);
    }

    public static Parent newInstance(int i)
    {
        if(parentMap.containsKey(i))
            return parentMap.get(i);

        return new Parent(i);

    }
}

/* Other class */

public class ExtendedParent extends Parent{
    public ExtendedParent(int i){
        super(i);//I should use the factory at this point...
    }

    public static main(String[] args){
        /*What I am trying to achieve*/
        Parent p1 = new ExtendedParent(1);
        Parent p2 = new ExtendedParent(1);

        if(p1.equals(p2))
            System.out.println("This is what i aim to get!!!!");

    }
}

Remade the code to demonstrate my problem clearly.

Can someone help me out? =D

Thanks in advance!

matutano
  • 93
  • 3
  • 9
  • Let `A` extend `B` which extends `SuperClass` ? Your `ExtendedParent` doesn't extend `Parent` ! There are multiple errors in that code . You can do what you want by overriding the `equals()` in your subclass. – AllTooSir Jun 11 '13 at 10:58
  • 3
    2 instances of a class can hold the same instance of an ancestor of the class as a member. If that is enough of a workaround. That would be composition before inheritance ... – Fildor Jun 11 '13 at 10:59
  • I forgot to add the extends keyword, corrected now. – matutano Jun 11 '13 at 11:02
  • I know they can hold them as a member, but my conceptual model really required one class to behave has the other. If there is no other solution I will have to live with it. – matutano Jun 11 '13 at 11:03
  • In Java instances do not inherit from anything. Classes do. – tbsalling Jun 11 '13 at 11:03
  • If your goal is that p1.equals(p2) you can just override the equals() method. If you do so, you'll also need to override hashcode() – Guillaume Jun 11 '13 at 11:22
  • Overriding equals is not an option. The reference to the Parent must be shared. – matutano Jun 11 '13 at 11:33
  • If you do not override `equals` it is the identity check `p1 == p2` and an object is always only identical to itself. – Michael Butscher Jun 11 '13 at 15:26

3 Answers3

1

I see two alternatives:

  • Make the relevant parent's attributes and methods static, so that they are shared among all descendants.
  • Replace the parent class with an interface and share an attribute of the original parent class between subclass instances.
Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55
  • This would not solve my problem, I want to do this: Parent p1 = new ExtendedParent(1); Parent p2 = new ExtendedParent(1); assertTrue(p1.equal(p2));//Woow factor – matutano Jun 11 '13 at 11:14
  • @matutano you could implement `Parent#equals` to check if the ids are equal – Adrian Panasiuk Jun 11 '13 at 11:18
  • Note that you are not just sharing the parent object, you are actually returning the *same* object from two different constructor calls. You can't do that with constructors, but it's easy to do it with a factory class. – Nicola Musatti Jun 11 '13 at 11:18
  • Adrian's is a valid suggestion: parent objects may not be shared, but there's no reason why they shouldn't be *equivalent*. – Nicola Musatti Jun 11 '13 at 11:23
  • Yes, but I can't use the factory class in the ExtendedParent, I was trying obtain the instance either by instanciating a new Parent or a new ExtendedParent. I reaching the conclusing that is just not possible. The only solution is to have the Parent instance as a member of ExtendedParent :\ – matutano Jun 11 '13 at 11:24
1

Make ExtendedParent instances forward calls to a Parent instance they keep as a member. And methods that should not only forward the calls, add the additional processing that distinguishes ExtendedParent from Parent.

Adrian Panasiuk
  • 7,249
  • 5
  • 33
  • 54
  • That is what I have at this moment. I thought there could be some workaround. I am reaching the conclusing that there isn't. Autoboxing should be available to the programmer, that would solve this problem! :P – matutano Jun 11 '13 at 11:29
1

You can use inner class. You can even make several distinct types share same parent class object.This would not be inheritance, but the result will be exactly what you are looking for:

public class Test {

    private final String text;

    Test(String text) {
        this.text = text;
    }

    public static void main(String[] args) throws Exception {
        Test t = new Test("Text");
        A a = t.new A();
        B b = t.new B();
        a.printA();
        b.printB();
    }

    class B {
        public void printB() {
            System.out.println(text);
        }
    }

    class A {
        public void printA() {
            System.out.println(text);
        }
    }
}
Mikhail
  • 4,175
  • 15
  • 31
  • This solution is equivelent to cloning, you created an object that looks like the original, but isn't the original. I need to have the same object, the same reference. – matutano Jun 11 '13 at 11:31
  • 2
    Two constructor invocations can't return same object. Rethink your design. Or override equals method. And this solution has nothing in common with cloning, Test instance will be the same. – Mikhail Jun 11 '13 at 11:34
  • I've compared it to cloning because attributes are being shared as class members. The solution is equivelent to have the Parent as a member. – matutano Jun 11 '13 at 11:48