嵌套类访问父类方法
发现一个问题 不明白什么原因
package mylibrary.webservice;
public class Parent {
protected void test1() {
}
public static class innerClass extends Parent {
public innerClass() {
super();
}
}
}
package mylibrary.webservice;
public class Test1 {
public static void main(String[] args) {
Parent.innerClass t = new Parent.innerClass();
t.test1();
}
}
Parent.innerClass t = new Parent.innerClass();
t.test1();
innerClass 是 Parent里的一个嵌套类,Test1是和Parent在一个package的测试类,这里面test1()方法是可见的,可是如果在别的package里实例化innerClass后,test1()方法就成不可见的,既然已经继承了为什么还是不可以用呢? --------------------编程问答-------------------- test1() 方法的修饰符是protected,表明它只有是同一个包中的类才可以访问 --------------------编程问答--------------------
可是innerClass 继承了 Parent, 在不同的package下应该也是可以用的啊。 --------------------编程问答-------------------- 因为它是在mylibrary.webservice包中继承的,所以只能在这个包中使用;
如果你在其它包中的一个类继承了这个Parent,那在这个包中的这个类就可以使用。 --------------------编程问答--------------------
+1 --------------------编程问答--------------------
三楼正解,再补充一下。
这是一个普遍的很容易搞混的问题我觉得,在其它package,innerClass可以被访问到,是因为它的访问范围是public,接下来牵涉到方法可见不可见,而方法test1之所以在其他包中不可见,是因为调用发生点所在类没有继承test1所在类。
而如果能访问的话,方法的protected就失去意义了。之所以造成可以访问的错觉,是因为类可访问造成的。 --------------------编程问答-------------------- 所以总结下来,关于方法能否调用有两点:
1. 方法是否属于该对象,自身的方法和继承的方法都属于对象,这是能否调用的前提,解决了有没有的问题。
2. 该方法的访问控制符(access modifier)与当前调用地点是否满足访问控制符的要求,解决了见没见的问题。
比如楼主提到的情形,方法调用发生在包外,调用点所在类又没有继承方法声明时所在类,因此不可调用(原因是方法不可见,不是没有)。而此时,调用方法的实例是继承了方法所在类这一事实构成了混淆点,它是继承,但不是方法调用发生点所在类的继承。 为什么要调用发生点所在类的继承,是因为访问控制的目的就是控制访问范围,当方法被访问(调用)时,它不希望在非继承外包类中被访问,这个限制是指方法调用地点,如果是指调用对象,那就要对实例所在类作访问控制了,但类的访问控制符不包括protected. --------------------编程问答--------------------
调用点所在的类继承了方法声明时所在类,也不能调用。。。为什么呢? --------------------编程问答--------------------
哪里有这个现象发生?
方法是package private或者是private的? --------------------编程问答-------------------- 楼主肯定是这样写的代码,才访问不了的,楼上你误导楼主了~
public class Test2 extends Parent{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parent.innerClass t = new Parent.innerClass();
t.访问不了test1()了;
}
}
--------------------编程问答--------------------
在包外调用点可以访问protect方法,是因为调用点所在类继承了方法声明所在类,而使得这个protect方法变成了调用点所在类的成员方法。
这里说调用点可以访问protect方法,是指你可以在调用点,像调用成员方法一样就调用它。而不是可以通过对象t去调用它
--------------------编程问答--------------------
你说的这两者本质是一样的,实例方法调用,都需要在类实例的主导下进行,隐含的就是this,也须满足调用发生所在类须是方法声明所在类的子孙类,也就是在继承线内,如果此类在包外的话。这个时候将焦点移开实例,集中在方法上。 --------------------编程问答-------------------- 继承可以使用只是说在继承类的内部可以使用。也就是innerClass的定义内部。
实例化innerclass后在包外访问,包外去看innerclass的test1的方法是protected的,就失去test1的访问了。
个人认为这种题意义不大,OOP的想法是一切皆对象,建模的时候你在一个对象内部定义一个子对象的唯一原因是说明这个子对象是外部的一部分,这种干嘛还要继承? --------------------编程问答--------------------
按照这个理解,一个类中的protected方法,如果子类继承了这个父类,必须还要调用点所在的类和父类在一个package下,这个方法对子类才是可见的吗? --------------------编程问答--------------------
不需要一个package下,只要继承就行。
可见不可见是在调用方法时才有的概念,当调用发生点所在类在方法声明类所在的包之外,就必须在方法继承线内才可调用protected方法。 --------------------编程问答--------------------
一个protected方法在子类内部是可以直接调用的,或者一个package下,在非package又没继承的情况下,即使通过子类也是访问不到这个方法的。
--------------------编程问答--------------------
方法要被调用不是通过子孙类就是本类。但可不可见是另外的问题了。
--------------------编程问答-------------------- 很简单的事情吧,你先清楚子类的位置。你那个例子里InnerClass跟Parent是在同一个包下的,就跟写了
package mylibrary.webservice;差不多效果,那么方法test1只在mylibrary.webservice这个包下可见,在其他包里自然访问不到。所以你要看这个类声明所在包,而不用关心在哪里实例化。
public class innerClass {
protected void test1() {
}
}
补充:Java , Java SE