Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将构造函数限制为同级使用-Java_Java_Oop_Inheritance_Access Modifiers_Siblings - Fatal编程技术网

将构造函数限制为同级使用-Java

将构造函数限制为同级使用-Java,java,oop,inheritance,access-modifiers,siblings,Java,Oop,Inheritance,Access Modifiers,Siblings,这可能是不可能的,但我正在尝试创建一个只有共享一个超类的类才能访问的构造函数,这几乎与受保护修饰符的逻辑相反。我假设没有修改器可以直接实现这一点,但是知道我要实现什么,有什么建议吗 public Account extends SomeEntity { //default public public Account() { } // I am wanting this constructor to be only available to sibling c

这可能是不可能的,但我正在尝试创建一个只有共享一个超类的类才能访问的构造函数,这几乎与受保护修饰符的逻辑相反。我假设没有修改器可以直接实现这一点,但是知道我要实现什么,有什么建议吗

public Account extends SomeEntity {

    //default public
    public Account() {

    }

    // I am wanting this constructor to be only available to sibling classes.
    // (those that share the same super class )
    <modifier> Account(Element accountElement) {

    }
}


public Accounts extends SomeEntity {

    private List<Account> accountList;

    //default public
    public Accounts() {

        Account newAcct = new Account(element);

        //looped loading up Generic list of Account
        this.accountList.add(newAcct);
    }
公共帐户扩展了某些实体{
//默认公众
公共帐户(){
}
//我希望这个构造函数只对兄弟类可用。
//(共享同一超级类的)
账户(要素账户要素){
}
}
公共帐户扩展到某个实体{
私人名单;
//默认公众
政府帐目(){
账户新账户=新账户(要素);
//循环加载帐户的通用列表
此.accountList.add(newAcct);
}
我正在使用RESTful web服务,并用XML响应构建对象,问题是如果我
获取
帐户列表,要将其构建到帐户对象列表中,我必须为每个帐户查询web服务,即使我已经有了信息,但这似乎完全没有效率

但是


我不想让我正在构建的API的普通用户能够以这种方式实例化Account对象。(使用
元素

没有类似的语言构造。从1.6开始,包(=默认)访问是城里唯一的Java机制


我相信你可以用堆栈做一些不好的事情,但我不推荐它们。

没有这样的语言结构。从1.6开始,包(=默认)访问是唯一的Java机制


我相信你可以用堆栈做一些不好的事情,但我不推荐它们。

我想看看工厂模式。你可能可以用工厂方法的访问修饰符玩游戏获取接近您所需的内容。您还可以在factory方法中使用反射,以获得更接近您所需的内容,而不是包访问所获得的内容。

我将查看factory模式。您可能可以使用factory方法的访问修饰符玩游戏获取接近您所需的内容。您还可以在factory方法中使用反射,以获得更接近您所需内容的内容,而不是package access获取的内容。

以下是我将尝试的内容(我尚未测试此方法):

帐户(对象参数){
如果(!super.getClass().isAssignableFrom(this.getClass())){
抛出新的AssertionError(“此构造函数仅对超类可用。”);
}否则{
//继续。。。
}
}
以下是我将尝试的方法(我还没有测试过此方法):

帐户(对象参数){
如果(!super.getClass().isAssignableFrom(this.getClass())){
抛出新的AssertionError(“此构造函数仅对超类可用。”);
}否则{
//继续。。。
}
}

很抱歉,我仍然不明白这种设计的意义。如果将方法添加到类中,其实现可能只会使用该类的私有数据,因此无法保证“兄弟”类也可以使用这些数据。换句话说,如果您的愿望得到了满足,您如何保证这种构造tor Account(对象arg0)实现不会将私有数据用于Account类?(因此Accounts类不可见)

在我看来,您似乎希望您的代码为单个帐户和帐户列表提供相同的接口—扩展SomeEntity类。使用复合模式可以更优雅地实现这一点

但是,如果您的目的是提供一个只有子类才会使用的自定义构造函数,那么为什么不在SomeEntity中声明自定义构造函数并使该类抽象呢

此外,请记住,您可以这样做:

public Account() {
  this(new arg0());
}

Account(Object arg0) {

}

不过,不确定这是否有帮助。

抱歉,我仍然不明白这种设计的意义。如果将方法添加到类中,则其实现可能仅使用该类的私有数据,因此无法保证“兄弟”类也可以使用此数据。换句话说,如果您的愿望得到满足,如何您能保证构造函数帐户(对象arg0)实现不会将私有数据用于帐户类吗?(因此对帐户类不可见)

在我看来,您似乎希望您的代码为单个帐户和帐户列表提供相同的接口—扩展SomeEntity类。使用复合模式可以更优雅地实现这一点

但是,如果您的目的是提供一个只有子类才会使用的自定义构造函数,那么为什么不在SomeEntity中声明自定义构造函数并使该类抽象呢

此外,请记住,您可以这样做:

public Account() {
  this(new arg0());
}

Account(Object arg0) {

}

不过,不确定这是否有帮助。

有一种方法可以模拟C++的friend功能,从而实现您想要的结果

警告:这是一种人为的技术,只有在没有其他解决方案时才应使用!

由于在本例中没有修饰符可以实现您想要的功能,所以技巧是将访问限制移动到另一个应用修饰符的位置。为此,请向构造函数添加一个键参数。该键属于只能由允许的“同级”类(即给定类的子类)实例化的类

因此,限制被移动到公共超类,在该超类中,可以使用常用的修饰符限制密钥的创建

以下是一个例子:

public class CommonSuperClass {
    public static final class Key {
        private Key() {}
    }

    // This is the only way to create a key, and it's protected
    protected final Key createKey() {
        return new Key();
    }
}

public class Account {
    // The restricted constructor can even be public
    public Account(Key key) {
        // Everybody can try with null, but we're not that stupid
        // Of course any RuntimeException can be thrown instead
        if (key == null) throw new UnsupportedOperationException();
    }
}

public class AllowedSibling extends CommonSuperClass {
    public void foo() {
        // I'm allowed
        new Account(this.createKey());
    }
}

public class DeniedClass {
    public void foo() {
        // This doesn't compile
        new Account(new Key());

        // This will throw an exception
        new Account(null);
    }
}

有一种方法可以模拟C++的friend特性,从而实现您想要的结果

警告:这是一种人为的技术,只有在没有其他解决方案时才应使用!

由于在本例中没有任何修改器可以执行您想要的操作,所以技巧是将访问限制移动到另一个位置w
public class Base {
    protected interface Factory {
        Base getInstance(Element e);
    }

    private static Map<Class<?>, Factory> registry = new HashMap<Class<?>, Factory>();
    protected static void register(Class<?> c, Factory f) { registry.put(c, f); }
    protected static <T extends Base> T create(Class<T> c, Element e) {
        return (T) registry.get(c).getInstance(e);
    }
}

public class Derived1 extends Base {
    protected Derived1(Element e) { }
    private static class Derived1Factory implements Factory {
        public Derived1 getInstance(Element e) {
            return new Derived1(e);
        }
    }

    static {
        register(Derived1.class, new Derived1Factory());
    }
}

public class Derived2 extends Base {
    protected Derived2(Element e) { }
    private static class Derived2Factory implements Factory {
        public Derived2 getInstance(Element e) {
            return new Derived2(e);
        }
    }

    static {
        register(Derived2.class, new Derived2Factory());
    }

    public void method() {
        Element e = null;
        ...
        // Put some element in e
        ...
        // This is what you were trying to do
        Derived1 d1 = create(Derived1.class, e);
    }
}
public class SomeEntity
    protected void init(Element accountElement) {}

public class Account extends SomeEntity 

    public Account() 
        ....

    protected void init(Element accountElement)
        ....


public class Accounts extends SomeEntity

    Account newAcct = new Account();
    newAcct.init(element);