Java面向對象(三) 六、面向對象特征之一:封裝性 6.1 封裝性的引入: 當我們創建一個類的對象以後,我們可以通過"對象.屬性"的方式,對對象的屬性進行賦值。這裡,賦值操作要受到屬性的數據類型和存儲範圍的制約。除此之外,沒有其他制約條件。 但是在實際問題中,我們往往需要給屬性賦值加入額外的限制條 ...
Java面向對象(三)
目錄六、面向對象特征之一:封裝性
6.1 封裝性的引入:
當我們創建一個類的對象以後,我們可以通過"對象.屬性"的方式,對對象的屬性進行賦值。這裡,賦值操作要受到屬性的數據類型和存儲範圍的制約。除此之外,沒有其他制約條件。
但是在實際問題中,我們往往需要給屬性賦值加入額外的限制條件。這個條件就不能在屬性聲明時體現,我們只能通過方法進行限制條件的添加。同時,我們需要避免用戶再使用"對象.屬性"的方式對屬性進行賦值。則需要將屬性聲明為私有的(private)。此時,針對於屬性就體現了封裝性。
6.2 封裝性的體現:
將類的屬性xxx私有化(private),同時,提供公共的(public)方法來獲取(getXxx)和設置(setXxx)此屬性的值。
註:上面的情況只是 Java 封裝性的體現之一,封裝性的體現還有:
-
不對外暴露的私有方法;
-
單例模式(將構造器私有化);
-
如果不希望類在包外被使用,則將類設置為預設
……
6.3 封裝性的體現,需要許可權修飾符來配合:
-
Java規定的4種許可權(從小到大排列):private、預設、protected 、public
-
4 種許可權可以用來修飾類及類的內部結構:屬性、方法、構造器、內部類
-
具體的:
4種許可權都可以用來修飾類的內部結構:屬性、方法、構造器、內部類
修飾類的話,只能使用:預設、public
- public類可以在任意地方被訪問。
- default類只可以被同一個包內部的類訪問。
6.4 總結封裝性:
Java提供了4種許可權修飾符來修飾類及類的內部結構,體現類及類的內部結構在被調用時的可見性的大小。
七、類的成員之三:構造器(constructor)
7.1 構造器的作用:
-
創建對象
-
初始化對象的信息
7.2 構造器的特征:
- 它具有與類相同的名稱。
- 它不聲明返回值類型。(與聲明為void不同)。
- 不能被 static、final、synchronized、abstract、native 修飾,不能有 return 語句返回值。
public class PersonTest {
public static void main(String[] args) {
//創建類的對象:new + 構造器
Person p = new Person();
Person p1 = new Person("Tom");
System.out.println(p1.name);
Person p2 = new Person("Jay", 20);
System.out.println(p2.name + " " + p2.age);
}
}
class Person{
//屬性
String name;
int age;
//構造器(重載)
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
public Person(String n,int a){
name = n;
age = a;
}
}
7.3 註意:
-
Java語言中,每個類都至少有一個構造器。如果沒有顯式的定義類的構造器的話,則系統預設提供一個空參的構造器,預設的空參構造器的許可權取決於該類的許可權。
-
定義構造器的格式:許可權修飾符 類名(形參列表){}。
-
一個類中定義的多個構造器,彼此構成重載。
-
一旦我們顯式的定義了類的構造器之後,系統就不再提供預設的空參構造器。
-
一個類中,至少會有一個構造器。
-
父類的構造器不可被子類繼承。
7.4 屬性賦值先後順序:
-
預設初始化
-
顯式初始化
-
構造器中初始化
-
通過“對象.屬性“或“對象.方法”的方式賦值
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);
User u1 = new User(2);
System.out.println(u1.age);
u1.setAge(3);
System.out.println(u1.age);
}
}
class User{
String name; // 預設初始化
int age = 1; // 顯式初始化
public User(){
}
public User(int a){ // 構造器中初始化
age = a;
}
public void setAge(int a){
age = a;
}
}
/* 輸出:
1
2
3
*/
Java 記憶體分析:
對於 u1 對象的 age 屬性:首先是預設初始化為 0 ,然後是顯式初始化將 0 改為 1 ,接著是構造器初始化將 1 改為 2 ,最後是通過通過“對象.屬性“或“對象.方法”的方式賦值為 3。
八、JavaBean(拓展)
-
JavaBean是一種 Java 語言寫成的可重用組件。
-
JavaBean,是指符合如下標準的Java類:
- 類是公共的
- 有一個無參的公共的構造器
- 有屬性,且有對應的get、set方法
-
用戶可以使用JavaBean將功能、處理、值、資料庫訪問和其他任何可以 用Java代碼創造的對象進行打包,並且其他的開發者可以通過內部的 JSP 頁面、Servlet、其他JavaBean、applet程式或者應用來使用這些對象。用 戶可以認為JavaBean提供了一種隨時隨地的複製和粘貼的功能,而不用關心任何改變。
-
例子:
public class JavaBean {
private String name; // 屬性一般定義為private
private int age;
public JavaBean() {
}
public int getAge() {
return age;
}
public void setAge(int a) {
age = a;
}
public String getName() {
return name;
}
public void setName(String n) {
name = n;
}
}
九、UML類圖
-
+ 表示 public 類型, - 表示 private 類型,# 表示protected類型
-
方法的寫法:
方法的類型( + 、- ) 方法名(參數名:參數類型):返回值類型
十、this 關鍵字
10.1 this 關鍵字的使用:
-
this 可以用來修飾、調用:屬性、方法、構造器。
-
它在方法內部使用,即這個方法所屬對象的引用;在構造器內部使用,表示該構造器正在初始化的對象。
-
this理解為:當前對象 或 當前正在創建的對象。
10.2 this 修飾屬性和方法:
-
在類的方法中,我們可以使用"this.屬性"或"this.方法"的方式,調用當前對象屬性或方法。
但是,通常情況下,我們都選擇省略"this."。特殊情況下,如果方法的形參和類的屬性同名時,必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參。
-
在類的構造器中,我們可以使用"this.屬性"或"this.方法"的方式,調用當前正在創建的對象屬性或方法。
但是,通常情況下,我們都選擇省略"this."。特殊情況下,如果構造器的形參和類的屬性同名時,我們必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參。
10.3 this 調用構造器
-
可以在類的構造器中使用" this(形參列表)"的方式,調用本類中重載的其他的構造器。
-
構造器中不能通過"this(形參列表)"的方式調用自身構造器。
-
如果一個類中聲明瞭n個構造器,則最多有 n - 1個構造器中使用了 "this(形參列表)"。
-
"this(形參列表)"必須聲明在類的構造器的首行。
-
在類的一個構造器中,最多只能聲明一個"this(形參列表)"。
// 一個例子:
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Jerry",20);
System.out.println(p2.getAge());
}
}
class Person{
private String name;
private int age;
public Person(){
String info = "Person初始化時,需要考慮如下的1,2,3,4...(共40行代碼)";
System.out.println(info);
}
public Person(String name){
this();
this.name = name;
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);
this.name = name;
//Person初始化時,需要考慮如下的1,2,3,4...(共40行代碼)
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
// 省略了this,相當於return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
// 省略了this,相當於return this.age;
}
public void eat(){
System.out.println("人吃飯");
this.study();
}
public void study(){
System.out.println("人學習");
}
}