如何避免从外部世界创建B类对象,并且只允许通过A类

时间:2012-08-08 07:11:37

标签: java

如何避免从外部世界创建B类对象,并仅允许通过A类?

我有2个班级

public class A {
    B obj = null;
    public A() {
        obj = new B();
    }        
    public void methodA () {
        obj.methodB();
    }        
    // other methods
}

public class B {
    public void methodB () {
        // some logic            
    }
    //other methods
}

public class Client {
    public static void main (String s[]) {
        // Valid Call            
        A obj = new A();
        obj.methodA();  // Since methodB is called internally

        // Invalid Call , How to restrict this B object creation here ?
        B objB = new B();
        objB.methodB();

    }
}

9 个答案:

答案 0 :(得分:2)

我能想到的一个解决方案是使用A:KeyToB的内部静态类和私有构造函数,B需要实例化。因此,只有A可以实现B,它可以在不同的文件中。

public class A {
    B obj = null;
    public A() {
        obj = new B(instance);
    }
    public void methodA() {
        obj.methodB();
    }
    // other methods ..

    //The key to have the right to instanciate B, only visible in A
    private static KeyToB instance = new KeyToB();

    public static class KeyToB{
        private KeyToB() {
        }
    }
}

public class B {
    //The constructor is package visible, it need a non null instance of KeyToB . If someone use new B(null), it will get a RuntimeException
    B(KeyToB instance) {
        if (instance == null){
            throw new IllegalArgumentException("B can only be instanciated by A");
        }
    }
    public void methodB() {     
    }   
}

答案 1 :(得分:1)

尝试将类B作为类A的内部类,并将类B的范围指定为私有

class A {
    B b = null;
    public A() {
    b = new B();    
    }
     public void testA() {
       return b.methodB();
     }

    private class B {

         public void methodB () {             
                   // some logic                     
         }  

    }
}

http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html

答案 2 :(得分:1)

使用Inner Class的概念。

所有 Private 都可以 {{1>} (即附上课程)

Outer Class成员封闭类),其中反之亦然

因此,Inner Class外类Class AClass B 内部类

private

答案 3 :(得分:0)

一个简单的解决方案是将AB放在示例包中。然后将类B公开,但其构造函数package访问或protected

班级A将是:

package my;
public class A {}

和班级B将是:

package my;
public class B {
   B() {}
}

如果在包之外实际上不需要类B,您甚至可以使类本身成为包访问类。

答案 4 :(得分:0)

将B类放在与A相同的包中,并使其构造函数受包保护。只有同一个包中的类才能调用它。

答案 5 :(得分:0)

您可以使用私有构造函数使B成为A的内部(静态)类。

class B {

    public A createA() {
        A a = new A();
        return a;
    }

    public static class A {
        private A() {}
    }

}

答案 6 :(得分:0)

您可以使用私有静态嵌套类:

    public class A {
        private static class B {
            public void methodB () {
                // some logic            
            }
            //other methods
        }

        B obj = null;

        public A() {
            obj = new B();
        }        
        public void methodA () {
            obj.methodB();
         }        
         // other methods
   }

答案 7 :(得分:0)

public class A {

    private class B{

        private B(){

        }       
    }

    public B createB(){
        return new B();
    }

}

答案 8 :(得分:0)

这是解决方案,它的工作......

public class A {

    public static boolean isFromAClass = false;
    B obj = null;

    public A() {
        try {
            isFromAClass = true;
            obj = new B();
            isFromAClass = false;
        } catch (Exception e) {
        }
    }

    public void methodA() {
        System.out.println("methodA");
        obj.methodB();
    }
    // other methods
}

public class B {

    public B () throws Exception {
        if(!A.isFromAClass) {
            throw new Exception();
        }
    }
    public void methodB() {
        System.out.println("methodB");
        // some logic
    }
    //other methods
}

public class Client {

    public static void main(String s[]) throws Exception {
        // Valid Call
        A obj = new A();
        obj.methodA();  // Since methodB is called internally

        // Invalid Call , How to restrict this B object creation here ?
        B objB = new B(); // this line throws Exception
        objB.methodB();

    }
}

A,B,客户端类可以在任何包中。

使用public static boolean isFromAClass = false;这是实现的。

只有我需要改变,而不是泛化的异常,它应该被定制为Exception为 OutSideAClassBClassInstanceShouldNotBeCreated