Java的访问控制修饰符及其对应的访问权限:
-
public:
属性和方法可以被所有类访问。 -
protected:
包中的类和不同包的子类可以访问
package B;
public class FighterPlane {
protected String name;
protected int missileNum = 0;
public void fire() {
if(missileNum > 0) {
System.out.println("Now fire a missile!");
missileNum -= 1;
}
else {
System.out.println("No missile left!");
}
}
}
package A;
import B.*;
public class RunPlane extends FighterPlane{
private void init() {
name = "歼-20";
missileNum = 6;
}
public static void main(String args[]) {
RunPlane fp = new RunPlane();
fp.init();
fp.fire();
}
}
B包中的protected属性在A包中的子类中被访问,如果将B包中属性前的修饰符改为默认或者private则会报错。如果将B包中方法前的修饰符改为默认或者private也会报错,改为protected则不会报错。
- 默认:
包中的类可以访问。
package A;
class FighterPlane {
String name;
int missileNum = 0;
void fire() {
if(missileNum > 0) {
System.out.println("Now fire a missile!");
missileNum -= 1;
}
else {
System.out.println("No missile left!");
}
}
}
public class RunPlane extends FighterPlane{
private void init() {
name = "歼-20";
missileNum = 6;
}
public static void main(String args[]) {
RunPlane fp = new RunPlane();
fp.init();
fp.fire();
}
}
包中的子类可以访问。
package A;
class FighterPlane {
String name;
int missileNum = 0;
void fire() {
if(missileNum > 0) {
System.out.println("Now fire a missile!");
missileNum -= 1;
}
else {
System.out.println("No missile left!");
}
}
}
public class RunPlane{
public static void main(String args[]) {
FighterPlane fp = new FighterPlane();
fp.name = "Su-35";
fp.fire();
}
}
包中的非子类也可以访问。
- private:
只有本类可以访问。
子类对于从父类继承的哪些属性与方法是可见的:
只有从父类继承的private属性和方法是不可见的。
package A;
class FighterPlane {
private String name;
}
public class RunPlane extends FighterPlane{
private void init() {
name = "歼-20";
}
public static void main(String args[]) {
RunPlane fp = new RunPlane();
fp.init();
}
}
RunPlane的构造方法中name = "歼-20"报错——The field FighterPlane.name is not visible,如果将FighterPlane中name前的修饰符改为其他则不会报错。
组合及其作用:
组合(Composition),java代码复用的一种方法。顾名思义,就是使用多个已有的对象组合为一个功能更加复杂强大的新对象。体现的是整体与部分、拥有的关系。又因为在对象之间,各自的内部细节是不可见的,所以我们也说这种方式的代码复用是黑盒式代码复用。
package A;
class FighterPlane {
String name;
int missileNum = 0;
protected void fire() {
if(missileNum > 0) {
System.out.println("Now fire a missile!");
missileNum -= 1;
}
else {
System.out.println("No missile left!");
}
}
}
class AirLiner {
String name;
int seatNum = 0;
protected void sale() {
if(seatNum > 0) {
System.out.println("Now sale a ticket!");
seatNum -= 1;
}
else {
System.out.println("No seat left!");
}
}
}
public class RunPlane{
FighterPlane fp;
AirLiner al;
private void init() {
fp = new FighterPlane();
al = new AirLiner();
}
public static void main(String args[]) {
RunPlane rp = new RunPlane();
rp.init();
rp.fp.name = "Su-35";
rp.al.name = "C919";
rp.fp.fire();
rp.al.sale();
}
}
重载及其作用:
在类中定义了多个同名而不同内容参数的成员方法时,称这些方法是重载(overloading)方法。
class Parent{
public int getScore(){
return 3;
}
public int getScore(int i){
return i;
}
}
重载能满足对于能进行消息处理的接口方法有时既需要对其功能进行复用,同时又需要对其进行扩充(补充新的参数)的要求。
覆盖及其作用:
子类对父类参数相同、返回类型相同的同名方法重新进行定义,这种多态被称为覆盖(overriding)。
package A;
class FighterPlane {
String name;
int missileNum = 0;
protected void fire() {
if(missileNum > 0) {
System.out.println("Now fire a missile!");
missileNum -= 1;
}
else {
System.out.println("No missile left!");
}
}
}
class AirLiner extends FighterPlane{
protected void fire() {
if(missileNum > 0) {
System.out.println("Now sale a ticket!");
missileNum -= 1;
}
else {
System.out.println("No seat left!");
}
}
}
public class RunPlane{
AirLiner al;
private void init() {
al = new AirLiner();
}
public static void main(String args[]) {
RunPlane rp = new RunPlane();
rp.init();
rp.al.name = "C919";
rp.al.fire();
}
}
输出结果为:No seat left!
方法覆盖与引用替换结合,可使抽象类的声明在保证消息发送统一的前提下,具有消息结果执行上的相异性特点。