1. 程式人生 > >Java面向物件——類與方法

Java面向物件——類與方法

面向物件——能進行現實生活的抽象

世界是由一系列物件互相組合形成(多個物件之間的相互協作),每個物件有自己的屬性和方法。

通俗解釋:狗吃糧,狗和糧是兩個物件 ,吃是行為

每個物件——類,每個類有自己的屬性及方法

新興的程式設計正規化:

面向切面程式設計:EE-AOP

面向介面程式設計——介面優先原則

函數語言程式設計:Scala(JVM)

面向物件名字擴充套件:

面向物件三大特徵:

a.封裝性:將客觀事物封裝成抽象的類,,每個類都有自己的屬性與方法,並且類可以讓自己的資料與犯法只讓可信的類或物件操作,對不可信的進行資訊隱藏。內部操作對外部而言不可見,強調保護性

b.繼承性:可以實現現有類的所有功能,並且在無語重新編寫原有類程式碼的情況下進行功能上的擴充套件。

c.多型性:一個類例項的相同方法在不同情形下有不同的表現形式。好處:多型機制使得具有不同內部結構的物件可以共享相同的外部介面。(利用多型可以得到良好的設計)

類與物件的定義與使用

class 類名稱 {
    屬性1;
    屬性2;
    屬性n...;
        
    方法1(){}
    方法2(){}
    方法n(){}...
 }
 
  • 是共性的概念;物件是一個具體的、可以使用的事物。
  • 類的組成:方法(操作的行為)and屬性(變數,描述每個物件的具體特點)
  • 類是生產物件的藍圖,先有類才可以產生物件。物件的所有屬性與行為,一定在類中進行了完整定義。
  • 類中的屬性與方法(不帶static關鍵字的)只能通過物件呼叫
  • 類的設計原則:編寫類時,沒有額外說明,所有屬性必須使用private封裝(成員變數)
  • 類定義順序:

定義屬性 -> 定義構造方法 -> 定義普通方法

物件的產生:

物件在主方法中產生

產生語法:

類名稱 物件名稱 = new 類名稱

物件記憶體分析:

  • 先簡單的將Java中的記憶體區域分為棧記憶體和堆記憶體兩塊區域

棧記憶體(虛擬機器區域性變量表):存放的是區域性變數(各種基本資料型別/物件引用-物件名字)

堆記憶體:儲存物件(new表示在堆上新分配空間)

垃圾空間:沒有任何棧記憶體指向的堆記憶體空間

構造方法:

  • 抽象出一個類,若沒有給予一個構造方法,則有一個預設的構造方法;若給予了一個構造方法,則沒有預設的構造方法。

預設的構造方法:

public 類名(){
}
  • 意義:類中屬性初始化
1Person 2person = 3new 4Person();

1類名:通過哪個類產生物件

2產生的物件名,引用一塊堆記憶體

3開闢一塊堆記憶體

4構造方法

疑問:

Person person;

Person person=null;

上述兩種表達有何不同???

解答:

第一種只是宣告,沒有初始化,無法通過編譯;第二種是將person初始化為null,執行時可能會出現空指標異常。

  • 三大特徵:

a.構造方法名稱必須與類名稱相同

b.構造方法沒有返回值型別宣告(構造本身有返回值,返回當前構造的物件)

c.每個類中一定至少存在一個構造方法。如果沒有明確定義,系統會自動生成無參構造;若在類中自定義了構造方法,則                系統不會自動生成無參構造。

  • 屬性、構造方法、普通方法

屬性是在物件開闢堆記憶體時開闢的空間

構造方法是在使用new後呼叫的

普通方法是在空間開闢了、構造方法執行之後可以多次呼叫的

  • 構造方法過載:引數個數不同,可以創建出不同屬性資訊的物件
  • 在進行類定義時:定義屬性  ->  定義構造方法  ->  定義普通方法 
  • 匿名物件:
new Person("張三",20).getPersonInfo();

由於匿名物件不會有任何的棧空間所指向,所以使用一次後就成為垃圾空間。 

this關鍵字

a.表示呼叫方法

   只要在類中訪問類的屬性,一定要加上this關鍵字

b.表示呼叫本類方法

   (1)呼叫普通方法   this.方法名(引數)

            當有類的繼承關係時,表示本類方法一定要加上this關鍵字。否則,可加可不加。

   (2)呼叫構造方法   this.(引數)

            this呼叫構造方法必須放在構造方法首行;this呼叫構造方法不允許成環

c.表示當前物件

程式碼示例:

public class OOP{
	String name;
	int age;
	
	//無參的構造方法
	public OOP(){
		
	}
    //構造方法過載
	//有參的構造方法
	public OOP(String name,int age){
		this.name=name;		//物件的名字=賦值的名字
		this.age=age;
	}
	
	String personInfo(){
		return "這個人叫"+name+"年齡"+age;
	}
	
	//具體物件
	public static void main(String [] args){
		//物件1
		//建立物件
		OOP per1=new OOP();
		//對屬性賦值
		per1.name="Tom";
		per1.age=18;
		
		//物件2
		OOP per2=new OOP();
		per2.name="Mary";
		per2.age=20;
		
		//物件3
		OOP per3=new OOP("Alice",22);
		
		//引用傳遞
		//per1物件引用的地址賦值給砰然
		OOP per4=per1;
		per4.age=25;
		
		//per1變數引用指向空
		//per1=null;
		//per4=null;//堆上的person物件已經沒有變數引用它,但依然存在
		
		//呼叫物件的方法
		System.out.println(per1.personInfo());
		System.out.println(per2.personInfo());
		System.out.println(per3.personInfo());
	}
}

private實現封裝

將屬性、方法用private封裝後表示,被封裝的屬性與方法只能在本類中使用,類外部不可見。此時想要訪問被封裝的屬               性,必須提供getter和setter方法

  • setter方法:主要進行屬性內容的設定與修改

       getter方法:主要進行屬性內容的取得

  • 當類中有一個屬性不希望被外部訪問或修改,則不需寫setter方法

程式碼示例:

public class OOP{
	private String name;
	private int age;
	private String secret="***";
	private String hobby;
	
	//假設建立物件時必須同時賦予名字,因此,不提供無參的構造方法
	
	//有參的構造方法
	public OOP(String name){
		this.name=name;		//物件的名字=賦值的名字
	}
	
	//方法、行為
	public String personInfo(){
		return "這個人叫"+name+",年齡是"+age+",愛好是"+hobby;
	}
	
	//getter getXXX()  XXX為屬性名稱
	String getName(){
		return name;
	}
	
	int getAge(){
		return age;
	}
	
	String getSecret(){
		return secret;
	}
	
	String getHobby(){
		return hobby;
	}
	
	//setter setXXX()  XXX為屬性名稱
	void setAge(int age){
		this.age=age;
	}
	
	void setHobby(String hobby){
		this.hobby=hobby;
	}
}

public class OOPTest{
	public static void main(String [] args){
		//物件1
		//建立物件
		//假設姓名不得修改,因此不提供setName()方法
		OOP per1=new OOP("Tom");
		
		// 對屬性賦值
		per1.setAge(20);
		per1.setHobby("跑步");
		
		//OOP類的保護——封裝
		//外部程式要訪問 封裝的屬性 通過提供的getter方法訪問
		System.out.println(per1.getSecret());
		System.out.println(per1.personInfo());
	}
}