private
、protected
以及 public
,如果不加访问修饰符,表示包级可见。有资料将其称为default
。public
、protected
、default
、private
,他们可以修饰类、类中的成员变量和方法。访问控制权限 | 同一个类 | 同一个包 | 不同包中的子类 | 其他包中的类 |
---|---|---|---|---|
public | Yes | Yes | Yes | Yes |
protected | Yes | Yes | Yes | |
default | Yes | Yes | ||
private | Yes |
公共访问权限
,如果一个类中的成员或方法使用了public访问权限,就可以在所有类中被访问。不管是否在同一个包中。继承访问权限
,修饰父类的访问控制权限
,如果父类和子类不属于同一个包,想要继承父类拥有的成员但又不想设置为 public 访问权限,则可以设置为 protected 访问权限。同一个包中的类都可以访问,不同包的子类也可以访问。
包访问权限
,即不添加访问修饰符的时候 ,表示同一个包中可访问。私有访问权限
,被修饰的属性和方法只能被所在的类访问
,其他任何类都无法访问。应用场景:
单例模式,其中的属性和方法都是private
权限。信息隐藏或封装
。因此访问权限应当尽可能地使每个类或者成员不被外界访问
。子类中该方法的访问级别不允许低于父类的访问级别
。这是为了确保可以使用父类实例的地方都可以使用子类实例
,也就是确保满足里氏替换原则
。如父类方法的访问权限为protected,子类方法应该为protected或public。属性最好不能是公有的
,因为这么做的话就失去了对这个字段修改行为的控制,客户端可以对其随意修改。最好设置为private, 提供getter和setter方法,实现属性的修改。只能使用public或default
;内部类四种权限都可以。这时,内部类就像外部类的一个成员。TreeNode
要放在同一个Java文件中的话,只能是default权限。public class Test
,定义public class Hello
会报错。public class
,所有的class 都是default权限。这时java文件名可以随意
,不一定得跟class的名字一样。这种方式降低代码的可读性和可维护性,不建议使用!public class Test2 {
private String name;
public Test2(){
System.out.println("我是无参构造函数");
}
public Test2(String name){
System.out.println("我是有参构造函数");
this.name=name;
}
}
Test test=new Test()
会报错,因为找不到无参构造函数!public SuperExtendExample(int x, int y, int z) {// 子类的构造函数
super(x, y);// 显式调用父类的有参构造函数
this.z = z;
}
@Override
public void func() {// 子类重写类父类的func()
super.func();// 系那是调用父类的func()
System.out.println("SuperExtendExample.func()");
}
父类没有无参构造函数
,则子类不能从父类继承无参构造函数。父类没有无参构造函数的情况: 父类定义了有参构造函数,没有定义无参构造函数。There is no default constructor available in Father
public Child(String name) {
this.name = name;
}
父类提供了无参构造函数
,则子类的构造函数就可以不用显式地调用父类的构造函数
,在这种情况下编译器会默认调用父类提供的无参构造函数
。上面的代码不会提示错误,因为父类有无参构造函数。有无参构函数的情况:
① 父类没有定义构造函数,编译器自动为其生成无参构造函数;② 父类同时定义了有参和无参构造函数Private constructor 'Test()' is never used
。如果为protected,只有子类才能访问(貌似子类必须是同一个包。明明父类是public?)public class InitialOrderTest {
/* 静态变量 */
public static String staticField = "静态变量";
/* 变量 */
public String field = "变量";
/* 静态初始化块 */
static {
System.out.println( staticField );
System.out.println( "静态初始化块" );
}
/* 初始化块 */
{
System.out.println( field );
System.out.println( "初始化块" );
}
/* 构造器 */
public InitialOrderTest()
{
System.out.println( "构造器" );
}
public static void main( String[] args )
{
new InitialOrderTest();
}
}
静态变量-> 静态初始化块->变量->初始化块->构造器
使用super关键字
。大于等于
父类方法权限(public > protected > default> private
)。比如,如果父类方法的访问权限为protected,则子类方法可以为protected或public。public void hello(int a, int b) {
System.out.println(a + "," + b);
}
public void hello(int b,int a){
System.out.println(a + ";" + b);
}
从重载与重写的要求来看:
从多态性来看
编译期绑定
,即在编译时根据参数变量的个数和类型判断应该调用哪个方法
。运行期绑定
,即在运行是根据引用变量所指向的实际对象类型来调用方法
java中通常所说的多态
。