共计 2147 个字符,预计需要花费 6 分钟才能阅读完成。
前言
我以为程序是严谨的——沿着一个流程图一步一步走下去,那么结果就会自然地呈现出来——这是程序的一种美。
java 作为优秀的程序设计与开发语言,判断一个被 java 修饰符修饰的方法,变量,也应该有这样的美。
学习了网上各种各样的文章,我觉得这一流程可以表述为:
接下来细化流程图中我的一些表达。
同时为了简化表达,之后提及我们讨论的东西,即被修饰符修饰的方法 / 成员时,均使用“课题”一词。
同时修饰符修饰的对象可能是方法,也可能是成员变量。本文不单独讨论成员变量,因为按流程图判断为允许(调用),对于成员变量来说也就是允许(读写)。
正文
0. 内调用和实例调用
内调用:形如 this.method()
为内调用,显然,this
通常情况下可以省略。同时对方法的重写也归于此类。
实例调用:课题所属的类的实例变量调用课题即文中说的实例调用。若是静态方法无实例直接调用,亦归属此类。强调:此处的实例变量是课题所属的类的,而不能是课题所属的类的任一子类的。
1. 本类内调用
任意的课题(“课题”一词的含义请见前言段落的最后一段)显然是在一个类(接口)中的。这个类除了我们讨论的东西外,还可能有其它的方法。而在其它的方法中调用课题,就是我这里说的“类内调用”。
代码举例:
package packetA;
public class ParentA {private void privateMethod(){System.out.println("privatedMethod");
}
public void test(){privateMethod();
}
}
在方法 test
中对 privateMethod
方法的调用,即所谓类内调用。
=
2. 子类重写
即通过 extends
关键字,继承课题的类即这里的子类。
重写:对父类的方法的实现过程进行重新编写, 返回值和形参都不能改变。
代码示例:
package packetA;
public class ChildA extends ParentA {
@Override
protected void protectedMethod() {System.out.println("childA has overridden the protectedMethod.");
}
}
3. 子类内调用
代码示例:
package packetA;
public class ChildA extends ParentA {public void test(){this.protectedMethod();
}
}
4. 本类内部实例调用
代码示例:
package packetA;
public class ParentA {private void privateMethod(){System.out.println("privatedMethod");
}
protected void protectedMethod(){System.out.println("protectedMethod");
}
public void test(){ParentA parentA = new ParentA();
parentA.privateMethod();}
}
其中
public void test(){ParentA parentA = new ParentA();
parentA.privateMethod();}
这样先实例化一个实体后,在由这个实体调用方法的,就是本文说的“……实例调用”。
5. 同包下实例调用
在课题所在的类中实例调用显然也是同包下的实例调用,但这个情况并不会走到这个判断步骤来,会在“4. 本类内部实例调用”时走“是”而到达允许的终结状态。
是的,只要在相同的包下,或者在课题所在的类所在的包的子包下,不论是怎样的类——是课题所在类的子类?与课题所在类无关的类?无所谓——都能正常调用不是 private
修饰符修饰的课题。
如:
package packetA;
public class ParentA {private void privateMethod() {System.out.println("privatedMethod");
}
protected void protectedMethod() {System.out.println("protectedMethod");
}
}
package packetA;
public class DemoA {public static void main(String[] args) {ParentA parentA = new ParentA();
parentA.protectedMethod();}
}
能够正常运行。
6. 其它一切实例调用
是的,除开上述情况的其它一切实例调用,只要不是用 public
修饰符修饰的课题,全部拒绝。
即便是包外部的子类内调用 protected
修饰的课题(代码如下),也同样禁止。
package packetB;
import packetA.ParentA;
public class GreenhatChild extends ParentA {public void test(){ParentA parentA = new ParentA();
parentA.protectedMethod();}
}
test
方法是无法被运行的,不论是单元测试还是在主函数中示例一个 GreenhatChild
类再调用 test
方法。