我有一个受保护的方法(我不希望在超类或其子类之外看到此方法)。我想在复制构造函数中使用它,但是不能。码:

public class Superclass {
    protected HashMap<Object, Object> getData() {
        return new HashMap<>();
    }
}

public class Subclass extends Superclass {
    public Subclass(Superclass abstractClass) {
        init(abstractClass);
    }

    private void init(Superclass abstractClass) {
        //ERROR!!! getData has protected access in Superclass
        for (Map.Entry<Object, Object> entry : abstractClass.getData().entrySet()) {
            //do something
        }
    }
}


如果我仍然想从超类对象创建Subclass对象而不暴露getData()方法,该如何解决这个问题?

编辑类在不同的包中!

最佳答案

在同一个程序包中,以下对我适用:

超类:

public class Superclass {
    protected List<String> getData() {
        return Arrays.asList("a", "b", "c");
    }
}


子类:

public class Subclass extends Superclass {

public static void main(String[] args) {
    Superclass superObject = new Superclass();
    Subclass subObject = new Subclass(superObject);
}

    public Subclass(Superclass abstractClass) {
        //ERROR!!! getData has protected access in Superclass
        for (String entry : abstractClass.getData()) {
            System.out.println(entry);
        }
    }
}


提醒您,我不确定这实际上是您要尝试执行的操作。例如,为什么要在Superclass的构造函数中传递Subclass的实例?另外,您有一个HashMap而不是List,但是HashMaps不是Iterable,因此您不能在它们上使用扩展的for循环。

然而:
如果这些类位于不同的程序包中,则情况会发生变化。查看语言规范;在§6.6.1中说:


  [I]如果成员或构造函数被声明为受保护的,则仅当以下条件之一为真时,才允许访问:
  
  
  对成员或构造函数的访问从包含声明受保护的成员或构造函数的类的包内进行。
  如第6.6.2节所述,访问是正确的。
  


并且§6.6.2指出:


  可以从包的外部访问对象的受保护成员或构造函数,而在包中只能通过负责该对象实现的代码声明该对象。


现在,由于不认为在init方法中调用函数负责实现,因此您可能无法在此处访问该成员。抱歉,这就是该语言的工作方式。

10-07 19:57
查看更多