Java设置实例的超级实例

时间:2011-12-29 11:53:21

标签: java class inheritance super superclass

我可能无法谷歌搜索正确的单词,但我无法找到以下问题的答案。

是否可以显式设置新类实例的超类。例如。我有一个SuperClazz实例,想要创建Clazz的新实例,扩展SuperClazz。我可以做这样的事情(代码就是我想要做的,它不能编译,也不正确):

    class Clazz extends SuperClazz{

Clazz(SuperClazz superInstance){
    this.super = superInstance;
}
}

4 个答案:

答案 0 :(得分:6)

你正在混合继承和授权。当一个对象调用

super.doThis();

它不会在另一个具有对象超类类型的对象上调用doThis。它称之为自己。 thissuper是一回事。 super只允许访问超类中定义的方法的版本,并在子类中重写。因此,更改超级实例没有意义:没有超级实例。

答案 1 :(得分:3)

超类总是隐式实例化,所以你不能这样做 - 在扩展类中“植入”超类。您可能想要的是复制构造函数。

答案 2 :(得分:1)

我认为您在使用的含义或术语方面存在一些误解。

实例(或对象)是您在运行时使用new Clazz()创建的。你不能改变它(除非你使用字节码修改技巧)。 你真正想要的是创建2个类:基类及其子类。这是最简单的例子。

class SuperClazz {
}

class Clazz extends SuperClazz {
}

如果要从子类的构造函数中调用exlplitly超类构造函数,请使用super():     Clazz扩展SuperClazz类{         public Clazz(){             超();         }     }

答案 3 :(得分:0)

我不能声称这将始终有效,您应该始终尽可能使用复制构造函数,但在某些情况下(例如您无权更改代码或不想产生复杂性),您可以使用它(例如:),

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)

我使用上面的例子在套接字内挂钩一些监视器

但你必须谨慎:

1- 反射很复杂:有时字段被用于同步或更复杂的东西,你可能不应该更新静态(或更明确地说是静态最终)字段,你应该对你代理的类的内部有适当的了解它,并进行一些繁重的测试以确保一切顺利

2- 反射在运行时很慢:测试它,如果它适合你就让它在那里