3

I might just be unable to google for the right words, but I can't find an answer to the following question.

Is it possible to explicitly set the superclass of a new class instance. E.g. I have a SuperClazz instance and want to create a new instance of Clazz which extends SuperClazz. Can I just do something like this (the code is just what I want to do, it doesn't compile and is not correct):

    class Clazz extends SuperClazz{

Clazz(SuperClazz superInstance){
    this.super = superInstance;
}
}
2
  • this.super would not be a class but an instance. And there is no such thing as the superinstance, because super is the instance itself. Commented Dec 29, 2011 at 11:55
  • 3
    Maybe you can rephrase your question and ask what "real-world" problem you are facing which you want to solve using this construction. Commented Dec 29, 2011 at 11:57

4 Answers 4

7

You're mixing inheritance and delegation. When an object calls

super.doThis();

it doesn't call doThis on another object which has the type of the object's superclass. It calls it on himself. this and super are the same thing. super just allows to access the version of a method defined in the superclass, and overridden in the subclass. So, changing the super instance doesn't make sense: there is no super instance.

Sign up to request clarification or add additional context in comments.

Comments

4

The super class is always instantiated implicitly, so you cannot do it — "plant" the super class inside an extending class. What you probably want is a copy constructor.

1 Comment

Yes I wanted a way around having to use a copy constructur.
1

I think you have some missunderstanding in meaning or terms you are using.

Instance (or object) is what you create using new Clazz() at runtime. You cannot change it (unless you are using byte code modification tricks). What yo really want is to create 2 classes: base class and its subclass. Here is the simplest example.

class SuperClazz {
}

class Clazz extends SuperClazz {
}

If you want to call exlplitly constructor of super class from constructor of subclass use super(): class Clazz extends SuperClazz { public Clazz() { super(); } }

1 Comment

No, I think I am using the right terminology.The problem is that java seemingly doesn't have a notion of an super instance. I was working with JS lately where you can mess around with the prototype instance, therefore I though java might keep the instance of the super class separated from the instance of the sub class, but this isn't the case? (Yes I know JS and Java are two different things, I just though this certain aspect had some origin from java...)
0

i cant claim that this will always work, you should always use copy-constructor as far as you can but in some cases (like you dont have access/right to change code or dont want to produce complexities) you can use this (example:),

import java.lang.reflect.Field;
import java.net.Socket;

public class SmarterSocket extends Socket {

    public SmarterSocket(Socket s) {
        super(); // default constructor for super instance

        // will iterate over public/private fields of "s" (superclass not included)
        for(Field f : s.getClass().getDeclaredFields()){
            try {
                f.setAccessible(true);
                f.set(this,f.get(s));
            }catch (Exception ignored){}
        }

    }

    public void doSmartStuff(){
        System.out.println("smarter");
    }
}

...

public static void main(String[] args){

        try {
            Socket s = new Socket();
            s.connect(new InetSocketAddress("stackoverflow.com",80));
            SmarterSocket ss = new SmarterSocket(s);
            ss.close();
            System.out.println("is SmartSocket closed: " + ss.isClosed());
            System.out.println("is Socket closed: " + s.isClosed());
            s.getOutputStream().write("hellow".getBytes()); // write to s
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

is SmartSocket closed: true
is Socket closed: false

java.io.IOException: Socket Closed
    at java.base/java.net.AbstractPlainSocketImpl.getOutputStream(AbstractPlainSocketImpl.java:489)
    at java.base/java.net.Socket$3.run(Socket.java:972)
    at java.base/java.net.Socket$3.run(Socket.java:970)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.net.Socket.getOutputStream(Socket.java:969)
    at Main.main(Main.java:47)

i used above example for hooking some monitors inside socket

but you have to be cautious:

1- reflection is complex: sometimes fields are being used for synchronization or more sophisticated stuff, you probably shouldn't update static (or more clearly static final) fields, you should have proper knowledge about internals of the class you are proxying it,and do some heavy tests to make sure everything is going smoothly

2- reflection is slow in runtime: test it, if it suit you let it be there

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.