一. 概要。
在任何关系中,具有关系所涉及的各方都遵守的清晰的边界时很重要的。每个类或者对象都有其能被修改和不能触犯的东西,访问权限就是提供这样的一个边界保障。
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法。
注意:类不能用private 和 protected 修饰。
二.继承
子类继承父类主要有两种情况:
1.一种是在继承之后,在父类的基础上添加新的方法,满足要求。
2.重新实现父类的某些方法,改写其中的具体实现,这种方式称为覆盖。
继承中的构造器问题
1. 构造的调用先后顺序
public class A {
System.out.println(" 初始化父类A");
}
public class B extends A {
public B() {
System.out.println(" 初始化子类B");
}
}
上面定义了两个类A,B .B类继承于A类,现在实例化B类:
B b = new B();
得到的运行结果如下:
I/System.out: 初始化父类A
I/System.out: 初始化子类B
先调用了父类的到构造方法,先实例化父类的实例再实例化子类实例。
2.如果父类没有默认的构造方法或者是没有空参数的构造方法的时候,子类会提示相应的错误。
如下代码所示,注释掉A类中的无参构造方法,编辑器对B类的构造方法提示 there is no default constructor
public class A {
/*public A() {
System.out.println(" 初始化父类A");
}*/
public A(int a) {
System.out.println(" 初始化父类A = "+ a);
}
}
3.B类默认时要调用A类的无参构造方法,例如上面这样A类的无参构造方法没有实现,或者B类确实需要调用A类的某个带参数的构造方法的时候怎么处理?
public class B extends A {
public B(int b) {
super(b);
System.out.println(" 初始化子类B");
}
}
再B类的构造方法中通过super关键子调用父类A的带参数的构造方法。
继承中方法和成员变量的调用和规则
1. 对象在调用方法和成员变量的时候,都是先查询当前子类对象本身是否有重写该方法,如果没有就会进入父类中调用父类存在的该方法。如果被调用的父类的方法中再调用的某个方法有被子实现,那么仍旧会调用到子类重写的该方法。
如下时简单的代码示例,加深理解和印象:
父类A代码:
public class A {
public int a = 5;
public A(int a) {
System.out.println(" 初始化父类A = "+ a);
}
public void f1(int f){ //父类的f1调用了f2(String f)方法
f2(""+f);
}
public void f2(String f){
System.out.println(" A类 f2");
}
}
子类B代码:
public class B extends A {
public B(int b) {
super(b);
System.out.println("初始化子类B");
}
//子类B重写了A的f2方法(重写必须保持参数一致,返回值一致,方法名相同)
@Override
public void f2(String f) {
System.out.println("B类 f2");
}
}
调用代码:
B b = new B(2);
b.f1(2); //b.f1(2)调用的时父类A中继承而来的f1方法。f1中调用的f2()是子类中重写过的方法。
所以运行结果如下:
I/System.out: 初始化父类A
I/System.out: 初始化子类B
I/System.out: B类 f2
三.重写(Override)和重载(Overload)
1.重写(Override)
概念:
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。注意
1)重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如:父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。
2)参数列表必须完全与被重写方法的相同;
3)返回类型必须完全与被重写方法的返回类型相同;
4)访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
5)父类的成员方法只能被它的子类重写。
6)声明为final的方法不能被重写。
7)声明为static的方法不能被重写,但是能够被再次声明。
2. 重载(Overload)
概念
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。注意:
1)被重载的方法必须改变参数列表(参数个数或类型不一样);
2)被重载的方法可以改变返回类型;
3)被重载的方法可以改变访问修饰符;
4)被重载的方法可以声明新的或更广的检查异常;
5)方法能够在同一个类中或者在一个子类中被重载。
6)无法以返回值类型作为重载函数的区分标准。