特定于类的方法可见性

时间:2014-05-30 12:43:31

标签: java visibility access-specifier

是否有一些面向对象的东西,你可以从某些类调用某些方法,但不是所有的方法?有类似protected类似的内容吗?

假设您有一个方法void foo()并且您希望程序员可以在几个类的类型中使用它(可能类似于使用Type变量(指定:{{1现在,也许有某种方式,没有继承带有T type的类,或者创建一个接口,来指定哪些类或类型的类可以访问该方法?

我猜这可能就像多继承和多态?但我仍然只希望类和某些类访问该方法而不改变方法的可见性。我希望可见性是特定于类的。

以下是一个例子:

foo()class A视为私有,但只有该类将其视为私有 foo()class B视为公共/受保护,但只有该类将其视为公开。

方法类型为foo()

我想更容易提问和回答的是:“是否有针对特定类别的可见性?”

4 个答案:

答案 0 :(得分:4)

在C ++中有类似的东西,它被称为friend classes。然而,Java不支持这个概念:

'Friends' equivalent for Java?

第二个选项是使用代码反射来访问类私有成员,但它不是一个干净的解决方案,只适用于protected个元素:

public class C1 {

    public C1()
    {
        x = "Hello Word!";
    }

    protected String x;
}

使用其他班级的方法:

String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);

编辑:经过一番研究后,我发现甚至可以访问私人会员:

Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);

答案 1 :(得分:1)

访问级别

Modifier    Class   Package Subclass  World
public       Y        Y       Y        Y
protected    Y        Y       Y        N
no modifier  Y        Y       N        N
private      Y        N       N        N

thats your lot, there are not any other access modifiers.

答案 2 :(得分:1)

不,在Java中没有那样。

您最接近的是将类放在同一个包中,此时他们可以访问任何未指定任何访问修饰符的成员。你不能指定特定的类。

某些案例中适用的另一个选项是使用嵌套类:

class Outer {
    private static class Inner {
    }
}

此处OuterInner可以访问彼此的私人会员。

答案 3 :(得分:0)

有一点点手法,你可以让一个班级看起来像是两个不同的班级:

// An interface.
interface A {
    public void a ();
}

// Another interface.
interface B {
    public void b ();
}

// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
    public void a () {

    }
    public void b () {

    }
}

// Pick either implementation from C and tell the world about it.
class D extends C implements A {
    // Do nothing - already done by C.
}

class E extends C implements B {
    // Do nothing - already done by C.
}

public void test() {
    A d = new D();
    B e = new E();
}

此处DE实际上是功能相同的对象,因为它们实际上都是C s。但是,在创建它们时,它们似乎是AB,它们是两个不同的接口。

不幸的是,我们无法隐瞒这样一个事实,即它们都扩展了C但是更进一步的手法,我们也可以用工厂做到这一点。

// Hide the guts of it all in a factory.
static class Factory {
    // Make sure you MUST use the factory methods.
    private Factory () {

    }

    // Construct an A.
    public static A newA () {
        return new D();
    }

    // Construct a B.
    public static B newB () {
        return new E();
    }
}