Java在子类的复制构造函数中使用超类的受保护方法

时间:2014-02-21 09:26:12

标签: java inheritance

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

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
        }
    }
}

如果我仍想在不暴露getData()方法的情况下从Superclass对象创建Subclass对象,我该如何解决这个问题呢?

编辑课程在不同的包中!

3 个答案:

答案 0 :(得分:3)

您在创建实例之前尝试访问方法。该实例尚未完全初始化。

调用从自己的构造函数构造的对象的方法可能会导致意外的行为,因为在构造函数完成之前,对象不会被一致地初始化。

答案 1 :(得分:1)

在同一个软件包中,以下对我来说很好:

超类

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]如果成员或构造函数被声明为protected,那么只有在满足下列条件之一时才允许访问:

     
      
  • 从包含声明受保护成员或构造函数的类的包中发生对成员或构造函数的访问。

  •   
  • 访问是正确的,如§6.6.2。

  • 中所述   

并且§6.6.2声明:

  

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

现在,由于在init方法中调用函数是而不是被视为负责实现,因此您可能无法在此处访问该成员。对不起,这就是语言的运作方式。

答案 2 :(得分:1)

无法从不同包中的类访问受保护的方法 - 请参阅http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html。您继承自Superclass这一事实并不重要,因为您尝试在基类本身上引用Superclass而不是时调用该方法。

所以,你想要做的事情不起作用 - 如果愿意,它会破坏Java的访问控制:你可以简单地从任何类继承并实现一个以超类引用作为参数的方法,然后访问超类的所有受保护方法(当然,您仍然可以从基类继承继承并访问超类的受保护成员,甚至是跨包)。

如果getData()是需要从其他包调用的方法,则需要将其公开。

另外,您应该重新考虑您的设计 - 是否真的有必要在Superclass构造函数中传递对Subclass对象的引用?