【问题标题】:make class only instantiable from specific class使类只能从特定类实例化
【发布时间】:2013-01-16 19:33:01
【问题描述】:

假设我有 3 节课 class1class2class3

我怎样才能让class1 只能被class2 (class1 object = new class1()) 实例化,而不能被 class3 或任何其他类实例化?

我认为它应该与修饰符一起使用,但我不确定。

【问题讨论】:

  • 您是否需要class1 才能被其他类访问,只是无法被实例化?

标签: java class modifier


【解决方案1】:

我想将您的课程重命名为 FriendShyStrangerFriend 应该能够创建 Shy,但 Stranger 应该不能。

此代码将编译:

package com.sandbox;

public class Friend {

    public void createShy() {
        Shy shy = new Shy();
    }

    private static class Shy {

    }

}

但这段代码不会:

package com.sandbox;

public class Stranger {

    public void createShy() {
        Friend.Shy shy = new Friend.Shy();
    }

}

此外,如果我们创建一个名为FriendsChild 的新类,则此也不会编译:

package com.sandbox;

public class FriendsChild extends Friend {

    public void childCreateShy() {
        Shy shy = new Shy();
    }

}

仔细想想,这种命名约定是有道理的。仅仅因为我是某人的朋友并不意味着我的孩子认识他们。

请注意,所有这些类都在同一个包中。据我所知,这是您正在寻找的场景。

【讨论】:

    【解决方案2】:

    除了使构造函数受保护之外的另一个选择:

    • class1 构造函数设为私有
    • 创建一个公共静态工厂方法,该方法需要class2 的有效实例才能返回class1 的实例

    【讨论】:

      【解决方案3】:

      使class1成为class2的内部类。

      【讨论】:

        【解决方案4】:

        更新

        制作protected 构造函数并将符合条件的类放在同一个包中,如果您希望包外的任何类来构造此实例,那么在此示例中您需要该类扩展ClassA

        如果您对其进行限制,请使用default 访问说明符

        package com.somthing.a;
        public class ClassA {
        
            ClassA() {
                super();
                // TODO Auto-generated constructor stub
            }
        }
        
        package com.something.a;
        public class ClassB {
            public static void main(String[] args) {
                new ClassA();//valid
            }
        }
        
        
        package com.something.c;
        public class ClassC {
            public static void main(String[] args) {
                new ClassA();// invalid
            }
        }
        

        【讨论】:

        • 为什么不包私有构造函数?
        • 我不同意这个答案。如果构造函数是受保护的,这意味着扩展它的类仍然可以调用构造函数。
        猜你喜欢
        • 2021-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多