【问题标题】:Restricted access on method call using Java polymorphism使用 Java 多态性限制方法调用的访问
【发布时间】:2012-10-03 13:53:48
【问题描述】:

我有这样的场景:

public class BaseClass {
    protected void protectedMethod(OtherObject object) {
    ...
    }
} 

public class Child1 extends BaseClass {
    @Override
    protected void protectedMethod(OtherObject object) {
        super.protectedMethod(object);
        // Custom Child1 logic
        ...
    }
}

public class Child2 extends BaseClass {
    @Override
    protected void protectedMethod(OtherObject object) {
        super.protectedMethod(object);
        // Custom Child2 logic
        ...
    }
}

然后,当我调用“protectedMethod”迭代“BaseClass”对象数组时,编译器给了我受保护的访问错误:

OtherObject other = new OtherObject();

BaseClass[] objects = {
    new Child1(),
    new Child2()
}

for (BaseClass object : objects) {
    object.protectedMethod(other); //this line gives me protected access error
}

但是如果我以不同的非多态方式做同样的事情,它工作正常。

OtherObject other = new OtherObject();

Child1 child1 = new Child1();
Child2 child2 = new Child2();

child1.protectedAccess(other);
child2.protectedAccess(other);

我不知道这两种方式有什么区别。

【问题讨论】:

  • 这两个子类是否与测试程序在同一个包中?
  • 你从哪里调用方法??
  • 不同之处在于,在第二个中您执行不同的方法(来自 Child1 和 Child2 类),但在第一个中您执行 BaseClass 的方法两次......也许您想制作 BaseClass(或protectedMethod) 抽象?
  • 您在每种情况下都调用了不同的方法。有时您拨打protectedMethod(),有时拨打protectedMethod(other),甚至拨打protectedAccess(other)。你的意思是这些都一样吗?
  • @Shark 我无法修改基类,因为它来自外部依赖项,也许它的创建者出于某种原因这样做了,但我似乎无法找出那个原因。跨度>

标签: java inheritance polymorphism protected


【解决方案1】:

在 Java 中,“protected”访问限定符不仅允许子类访问,还允许同一包中的其他类访问。

如果您的最后一个代码 sn-p 与 Child1 和 Child2 在同一个包中,那么它将可以访问 Child1 和 Child2 中的受保护方法。

编辑:

您可以通过在自己的包中引入自己的基类来解决此问题并保持多态性。

 public MyBaseClass extends BaseClass { 
    @Override
    protected void protectedMethod(OtherObject object) {
        super.protectedMethod(object);
    }
 }

 public Child1 extends MyBaseClass { ... }
 public Child2 extends MyBaseClass { ... }

然后使用您自己的基类类型的集合。

 NyBaseClass[] objects = {
    new Child1(),
    new Child2()
 }

 for (MyBaseClass object : objects) {
    object.protectedMethod(other); 
 }   

【讨论】:

  • 好的,但为什么它在第一种情况下仍然无法编译?有没有办法在不修改基类的情况下修改第一个场景以使其工作?
  • 可能基类与 Child1、Child2 和调用代码位于不同的包中。您可以通过使您自己的基类扩展 Baseclass 并将其放在同一个包中来使其工作。即 Baseclass
【解决方案2】:

带有protected修饰符的实例变量和方法只能在either in derived classother class in the same package中访问..

因此,您的 Base class 可能位于不同的包 pkg1 中,而您的 derived classes 和您使用 protected methodclass 可能在同一个包中包 pkg2different 来自 base 类包 pkg1..

然后通过上述属性,您将能够访问派生类的方法,因为它们在同一个包中。但是,由于base class 在不同的包中,而不是您的test class 的超类。 . 无法访问..

编辑 :- 好的,如果您无法更改 Base Class..

,您可以执行以下操作
for (BaseClass object : objects) {
    if (object instanceof Child1) {
        ((Child1)object).protectedMethod(other);

    } else if(object instanceof Child2) {
        ((Child1)object).protectedMethod(other);
    }
}

但是,这会从您的问题中消除所有多态的东西...这只是一种解决方法..

【讨论】:

  • 有没有办法修改第一个场景以使其在不修改基类的情况下工作?
  • @Jams..只有一种方法,如果您不想修改基类..将所有类移到同一个包中..您的问题将得到解决..
  • 我不能,因为 BaseClass 来自外部库
  • @Jams.. 因此,您可以将派生类和 Test 类从 package pkg2 移动到包 pkg1.. 您可以正确更改它们.. 在与基类是..
  • @Jams.. 好的等等.. 什么外部库??
【解决方案3】:

我会检查这个条目: Java Protected Method Accessibility

Protected 仅限于同一个包和孩子。如果你需要访问包外的方法,它应该是公开的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    相关资源
    最近更新 更多