《Java从小白到大牛》纸质版已经上架了!!!html
Java面向对象的封装性是经过对成员变量和方法进行访问控制实现的,访问控制分为4个等级:私有、默认、保护和公有,具体规则如表10-1所示。java
表 101 Java类成员的访问控制app
能否直接访问控制等级 | 同一个类 | 同一个包 | 不一样包的子类 | 不一样包非子类 |
---|---|---|---|---|
私有 | Yes | |||
默认 | Yes | Yes | ||
保护 | Yes | Yes | Yes | |
公有 | Yes | Yes | Yes | Yes |
下面详细解释一下这4种访问级别。ide
私有级别的关键字是private,私有级别的成员变量和方法只能在其所在类的内部自由使用,在其余的类中则不容许直接访问。私有级别限制性最高。私有级别示例代码以下:ui
// PrivateClass.java文件 package com.a51work6; public class PrivateClass { ① private int x; ② public PrivateClass() { ③ x = 100; } private void printX() { ④ System.out.println("Value Of x is" + x); } } // HelloWorld.java文件调用PrivateClass package com.a51work6; public class HelloWorld { public static void main(String[] args) { PrivateClass p; p = new PrivateClass(); //编译错误,PrivateClass中的方法 printX()不可见 p.printX(); ⑤ } }
上述代码第①行声明PrivateClass类,其中的代码第②行是声明私有实例变量x,代码第③行是声明公有的构造方法,构造方法将在第12章详细介绍。代码第④行声明私有实例方法。rest
HelloWorld类中代码第⑤行会有编译错误,由于PrivateClass中printX()的方法是私有方法。code
默认级别没有关键字,也就是没有访问修饰符,默认级别的成员变量和方法,能够在其所在类内部和同一个包的其余类中被直接访问,但在不一样包的类中则不容许直接访问。视频
默认级别示例代码以下:htm
// DefaultClass.java文件 package com.a51work6; public class DefaultClass { int x; ① public DefaultClass() { x = 100; } void printX() { ② System.out.println("Value Of x is" + x); } }
上述代码第①行的x变量前没有访问限制修饰符,代码第②行的方法也是没有访问限制修饰符。它们的访问级别都有默认访问级别。对象
在相同包(com.a51work6)中调用DefaultClass类代码以下:
// com.a51work6包中HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { DefaultClass p; p = new DefaultClass(); p.printX(); } }
默认访问级别能够在同一包中访问,上述代码能够编译经过。
在不一样的包中调用DefaultClass类代码以下:
// 默认包中HelloWorld.java文件 import com.a51work6.DefaultClass; public class HelloWorld { public static void main(String[] args) { DefaultClass p; p = new DefaultClass(); // 编译错误,DefaultClass中的方法 printX()不可见 p.printX(); } }
该HelloWorld.java文件与DefaultClass类不在同一个包中,printX()是默认访问级别,因此p.printX()方法没法编译经过。
公有级别的关键字是public,公有级别的成员变量和方法能够在任何场合被直接访问,是最宽松的一种访问控制等级。
公有级别示例代码以下:
// PublicClass.java文件 package com.a51work6; public class PublicClass { public int x; ① public PublicClass() { x = 100; } public void printX() { ② System.out.println("Value Of x is" + x); } }
上述代码第①行的x变量是公有级别,代码第②行的方法也是公有级别。调用PublicClass类代码以下:
// 默认包中HelloWorld.java文件 import com.a51work6.PublicClass; public class HelloWorld { public static void main(String[] args) { PublicClass p; p = new PublicClass(); p.printX(); } }
该HelloWorld.java文件与PublicClass类不在同一个包中,能够公有的printX()方法。
保护级别的关键字是protected,保护级别在同一包中彻底与默认访问级别同样,可是不一样包中子类可以继承父类中的protected变量和方法,这就是所谓的保护级别,“保护”就是保护某个类的子类都能继承该类的变量和方法。
保护级别示例代码以下:
// ProtectedClass.java文件 package com.a51work6; public class ProtectedClass { protected int x; ① public ProtectedClass() { x = 100; } protected void printX() { ② System.out.println("Value Of x is " + x); } }
上述代码第①行的x变量是保护级别,代码第②行的方法也是保护级别。
在相同包(com.a51work6)中调用ProtectedClass类代码以下:
// 默认包中HelloWorld.java文件 package com.a51work6; import com.a51work6.ProtectedClass; public class HelloWorld { public static void main(String[] args) { ProtectedClass p; p = new ProtectedClass(); // 同一包中能够直接访问ProtectedClass中的方法 printX() p.printX(); } }
同一包中保护访问级别与默认访问级别同样,能够直接访问ProtectedClass的printX()方法,上述代码能够编译经过。
在不一样的包中调用ProtectedClass类代码以下:
// 默认包中HelloWorld.java文件 import com.a51work6.ProtectedClass; public class HelloWorld { public static void main(String[] args) { ProtectedClass p; p = new ProtectedClass(); // 编译错误,不一样包中不能直接访问保护方法printX() p.printX(); } }
该HelloWorld.java文件与ProtectedClass类不在同一个包中,不一样包中不能直接访问保护方法printX(),因此p.printX()方法没法编译经过。
在不一样的包中继承ProtectedClass类代码以下:
// 默认包中SubClass.java文件 import com.a51work6.ProtectedClass; public class SubClass extends ProtectedClass { void display() { //printX()方法是从父类继承过来 printX(); ① //x实例变量是从父类继承过来 System.out.println(x); ② } }
不一样包中SubClass从ProtectedClass类继承了printX()方法和x实例变量。代码第①行是调用从父类继承下来的方法,代码第②行是调用从父类继承下来的实例变量。
提示 访问成员有两种方式:一种是调用,即经过类或对象调用它的成员,如p.printX()语句;另外一种是继承,即子类继承父类的成员变量和方法。
提示 访问类成员时,在能知足使用的前提下,应尽可能限制类中成员的可见性,访问级别顺序是:私有级别→默认级别→保护级别→公有级别。
静态变量和静态方法
有一个Account(银行帐户)类,假设它有三个成员变量:amount(帐户金额)、interestRate(利率)和owner(帐户名)。在这三个成员变量中,amount和owner会因人而异,对于不一样的帐户这些内容是不一样的,而全部帐户的interestRate都是相同的。
amount和owner成员变量与帐户个体有关,称为“实例变量”,interestRate成员变量与个体无关,或者说是全部帐户个体共享的,这种变量称为“静态变量”或“类变量”。
静态变量和静态方法示例代码以下:
// Account.java文件 package com.a51work6; public class Account { // 实例变量帐户金额 double amount = 0.0; ① // 实例变量帐户名 String owner; ② // 静态变量利率 static double interestRate = 0.0668; ③ // 静态方法 public static double interestBy(double amt) { ④ //静态方法能够访问静态变量和其余静态方法 return interestRate * amt; ⑤ } // 实例方法 public String messageWith(double amt) { ⑥ //实例方法能够访问实例变量、实例方法、静态变量和静态方法 double interest = Account.interestBy(amt); ⑦ StringBuilder sb = new StringBuilder(); // 拼接字符串 sb.append(owner).append("的利息是").append(interest); // 返回字符串 return sb.toString(); } }
static修饰的成员变量是静态变量,见代码第③行。staitc修饰的方法是静态方法,见代码第④行。相反,没有static修饰的成员变量是实例变量,见代码第①行和第②行;没有staitc修饰的方法是实例方法,见代码第⑥行。
注意 静态方法能够访问静态变量和其余静态方法,例如访问代码第⑤行中的interestRate静态变量。实例方法能够访问实例变量、其余实例方法、静态变量和静态方法,例如访问代码第⑦行interestBy静态方法。
调用Account代码以下:
// HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { // 访问静态变量 System.out.println(Account.interestRate); ① // 访问静态方法 System.out.println(Account.interestBy(1000)); ② Account myAccount = new Account(); // 访问实例变量 myAccount.amount = 1000000; ③ myAccount.owner = "Tony"; ④ // 访问实例方法 System.out.println(myAccount.messageWith(1000)); ⑤ // 经过实例访问静态变量 System.out.println(myAccount.interestRate); ⑥ } }
调用静态变量或静态方法时,能够经过类名或实例名调用,代码第①行Account.interestRate经过类名调用静态变量,代码第②行Account.interestBy(1000)是经过类名调用静态方法。代码第⑥行是经过实例调用静态变量。
前面介绍的静态变量interestRate,能够在声明同时初始化,以下代码所示。
public class Account { // 静态变量利率 static double interestRate = 0.0668; ... }
若是初始化静态变量不是简单常量,须要进行计算才能初始化,可使用静态(static)代码块,静态代码块在类第一次加载时执行,并只执行一次。示例代码以下:
// Account.java文件 package com.a51work6; public class Account { // 实例变量帐户金额 double amount = 0.0; // 实例变量帐户名 String owner; // 静态变量利率 static double interestRate; // 静态方法 public static double interestBy(double amt) { // 静态方法能够访问静态变量和其余静态方法 return interestRate * amt; } // 静态代码块 static { ① System.out.println("静态代码块被调用..."); // 初始化静态变量 interestRate = 0.0668; ② } }
上述代码第①行是静态代码块,在静态代码块中能够初始化静态变量,见代码第②行,也能够调用静态方法。
调用Account代码以下:
// HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { Account myAccount = new Account(); ① // 访问静态变量 System.out.println(Account.interestRate); ② // 访问静态方法 System.out.println(Account.interestBy(1000)); } }
Account静态代码块是在第一次加载Account类时调用。上述代码第①行是第一次使用Account类,此时会调用静态代码块。
本章主要介绍了面向对象基础知识。首先介绍了面向对象一些基本概念,面向对象三个基本特性。而后介绍了类、包、方法重载和访问控制。最后介绍了静态变量、静态方法和静态代码块。
http://edu.51cto.com/topic/1246.html
http://www.zhijieketang.com/group/5