黑馬程序員----java面向對象01(封裝、靜態)

---------------------- ASP.Net+Android+IOS開發.Net培訓、期待與您交流! ----------------------


一.面向對象的概念理解

1、把複雜的問題簡單化了

2、面向過程相當於一個執行者的行爲,而面向對象相當於一個指揮者的行爲

3、面向對象就是把一系列行爲和屬性封裝起來,然後通過直接調用擁有這些行爲和屬性的實體也就是對象來實現功能操作

4、面向對象中如果有我所需要的功能的對象(查閱API),直接調用此對象即可;如果沒有我需要的,那麼我需要自己創建對象並定義功能

 

二.類與對象的關係

1、類就相當於製作汽車的圖紙,而對象就相當於製作出來的汽車實體

2、應該是先有對象,然後纔有類,因爲只有有了對象實體以後,對此實體進行抽象,然後形成類

 

三.成員變量與局部變量的區別

1、成員變量在本類中都可以訪問,而局部變量只能在本函數或行爲體中被訪問

2、成員變量隨着對象的創建而產生,存在於堆內存中;局部變量存在於棧內存中

3、成員變量有默認初始化值null或0;局部變量沒有默認初始化值,不被初始化不能使用

 

四.創建對象,使用對象

public class CarDemo {
	public static void main(String[] args) {
		//1、創建一個對象c
		//Car c = new Car();  //new Car就是創建一個車對象,名字是c,顏色是紅色,輪胎數是4
		//c.color="藍色";  //改變c車的顏色。   注意:並沒有改變“圖紙”的顏色,只是改變了c車的顏色而已
//		c.run();      //  哪個對象調用的run,就是打印的那個對象的color和num
		
		//2、匿名對象(new Car())
		//Car c= new Car(); 
		compare(new Car());
		//c.color="黃色";    
		
		new Car().color="黃色";   //創建了一個新對象,改變了此對象的顏色 
		new Car().num=9;     //又創建了一個新對象,改變了此對象的輪胎數
			
		/*
		 * 總結:
		 * 匿名對象只能用來調用方法,匿名對象調用屬性是沒有意義的,因爲每new一次都是創建了一個新的對象,並不是對原來的屬性值進行改變
		 *	        
		*/
	}
	
	public static void compare(Car c){
		c.color = "black";
		c.num = 6;
	}
}


//定義一個車類(抽象的)
class Car
{
	//車的顏色
	String color="紅色";    
	//車的輪胎數
	int num=4;
	
	//車跑起來
	void run()
	{
		System.out.println("顏色是"+color+",輪胎數是"+num);
	}
}
 

 


 內存結構圖:

 

 

 

 五.匿名對象

1、顧名思義就是沒有具體的名字的對象,每new一次都是創建了一個新的對象,故調用此對象方法時只能使用一次
/*
* 總結:
* 匿名對象只能用來調用方法,匿名對象調用屬性是沒有意義的,因爲每new一次都是創建了一個新的對象,並不是對原來的屬性值進行改變
*       
*/


經典例子需求,創造一個汽車修配廠,對進來的汽車進行顏色或輪胎數的更改



六.封裝(private)

1、封裝是指隱藏對象的屬性和方法,僅對外提供訪問接口即可,這樣提高了程序的安全性,例如電腦機箱內部構造很複雜,但沒必要讓用戶看到,只需要提供給用戶背後插口即可。

2、對屬性的封裝在數據類型前加上private,並且提供set、get方法進行設置值和返回值

3、private用於修飾成員變量和成員函數

例子:控制傳入的年齡是否爲負數

public class Fengzhuang {
	public static void main(String[] args) {
		Person4 p = new Person4();
		p.setAge(39);   //傳入的年齡爲負數或者是正數
	}
}

class Person4{
	private int age;      //屬性基本上全部都要私有化
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		if(age>0 && age<130){     //在此判斷下傳入的年齡是否合法
			this.age = age;
			speak();
		}else{
			System.out.println("您輸入的年齡有誤!");
		}
	}
	void speak(){
		System.out.println("age是:"+age);
	}
}

 

七.構造函數

1、構造函數名與類名一致

2、構造函數可以重載,參數列表不一致

3、構造函數的作用是對對象進行初始化,一般對象再被創建時就擁有了一些屬性,這時候就用到了構造函數

4、對於禁止創建對象的類,可以把此構造函數私有化,這樣就無法創建對象了

代碼示例:

/*什麼時候需要構造函數:當一個對象一被創建就有默認的屬性或功能時需要定義
 * 
 * 
 * 用一個剛出生的小孩舉例講解
 * 1、剛出生有的有姓名,有的沒有姓名:構造函數的重載,函數名一致,參數列表不一致
 * (注意!!:一旦自定義了構造函數,那麼如果在創建對象時必須調用相同參數列表的構造函數)
 * 2、剛出生都會哭,在以後的成長中也會哭:構造函數中調用哭的方法,對象創建完後也可以調用哭的方法
 * 3、構造函數只能是在對象創建時被調用,每調用一次都是創建了一個新的對象,
 *    故要想給屬性賦予新的值,只能通過(對象.函數名)來賦值,而不能通過再一次創建對象改變,這樣是創建了一個新的對象
 * 4、如果禁止創建對象,可以把此構造函數私有化    private Person{}
 * */

public class Gouzaohanshu {
	public static void main(String[] args) {
		//1、分別是調用的不同構造函數
		Person5 p1 = new Person5();     
		Person5 p2 = new Person5("張三");
		Person5 p3 = new Person5("李四",30);
		
		p1.cry();     //2、p1在以後的成長中還會哭
		
		p1.setAge(50);
		System.out.println(p1.getAge());      //3、在這裏改變年齡只能通過對象調用函數去改變,而不能通過創建對象傳值去改變
	}
}

class Person5{
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	Person5(){      //!!!如果把這個構造函數註釋,那麼p1對象時無法被創建的
		cry();
	}
	Person5(String name){
		this.name = name;
		cry();
	}
	Person5(String name,int age){
		//this.name = name;
		this(name);           //this在構造函數之間的相互調用,(!!注意:此語句只能放在函數中的第一行)
		this.age = age;
		cry();
	}
	
	void cry(){
		System.out.println("哭");
	}
}


八、構造代碼塊

1、構造代碼塊優先於構造函數執行

2、構造代碼塊是在對象被創建時執行,並且只執行一次(每創建一此對象就執行一次)

代碼示例:

//構造函數與構造代碼塊的區別
/*
 * 不論什麼對象被創建都會首先調用構造代碼塊,然後再調用相對應的構造函數(優先級)
 * 
 */


public class Gouzaodaimakuai {
	public static void main(String[] args) {
		Person p1 = new Person();  //定義一個對象p1
		Person p2 = new Person("張三");  //定義一個對象p2
		p2.speak();
	}
}

class Person
{
	private String name;
	private int age;
	
	//構造方法一
	Person()
	{
		System.out.println("已調用構造函數");
	}
	
	//構造代碼塊
	{
		System.out.println("已調用構造方法");
	}
	
	//構造方法二
	Person(String name)
	{
		this.name = name;
	}
	
	//構造方法三 
	Person(String name,int age)
	{
		name = name;
		age = age;
	}
	
	public void speak()
	{
		System.out.println("name的值是:"+this.name);
	}
}

	
 


九.this關鍵字

/*
 * this的應用:定義一個比較兩個人年齡是否相同的功能,也就是是否是同齡人
 * 思路
 * 1、定義一個人類,並設置年齡屬性
 * 2、定義一個構造函數,用於初始化年齡
 * 3、定義一個比較年齡的函數,(注意!!這個函數是由兩個人中的一個來調用,所以只需要定義另外一個人的年齡作爲參數即可)
 * */

        public class This {
	
	public static void main(String[] args) {
		Person1 p1 = new Person1(20);
		Person1 p2 = new Person1(30);
		//Person1 p = new Person1(0);
		//System.out.println(p.compare(p1, p2));	
		System.out.println(p1.compare(p2));        //p1調用compare方法與p2的年齡進行比較
	}

}

class Person1{
	private int age;
	
	Person1(int age){
		this.age = age;
	}
	public boolean compare(Person1 p){
		return this.age==p.age;      //對於布爾型返回值,不需要定義if語句去判斷,直接返回結果即可
	}
} 

 

十.static關鍵字的運用

/*
 * static :是一個修飾符,用於修飾成員(成員變量和成員函數)
 * 1、可以直接別類名調用
 * 2、靜態成員隨着類的加載而加載,隨着類的消失而消失。類一被加載,靜態成員就存在於方法區(共享區)中了
 * 3、靜態成員優先於對象存在,因爲在類被加載之前對象不是存在的,所以對象是可以調用靜態成員的
 * 4、靜態成員被所有對象所共享
 * 5、靜態成員可以直接被類名調用:(類名.靜態成員)
 * 
 * 類變量和實例變量的區別
 * 1、存放位置
 * 類變量存在與方法區(共享區)中
 * 實例變量存在與堆內存中
 * 2、生命週期
 * 類變量隨着類的加載而產生,隨着類的消失而消失(長)
 * 實例變量隨着對象的創建而產生,隨着對象的消失而消失(短)
 * 
 * 
 * 靜態的利處與弊端
 * 利處
 *  把共有的數據存儲在共享區中,節省空間
 *  可以直接被類名調用
 * 弊端
 *  生命週期太長
 *  靜態成員只能訪問靜態成員 
 * */

public class Static_Demo {
	public static void main(String[] args) {
		Person p = new Person();
		p.name = "張三";
		p.print();
	}
}

class Person{
	String name;       //定義姓名  ,又稱爲成員變量或實例變量
	
	//定義國籍,在前面加上static以後,運行沒有改變,但是內存中發生了變化,country不存在堆內存中了,提取出來共享
	//又稱爲靜態成員變量或類變量
	static String country = "CN";    
	
	void print(){
		System.out.println(name+":::::::"+country);
	}
}
 

----------------------------------------------------------------------------------------------------


/*
 * 靜態代碼塊,格式:static{  }
 * 靜態代碼塊優先於主函數執行,並且只在類第一次被加載時執行,是用來給類進行初始化的
 * 
 * 執行順序:靜態代碼塊(類加載)------>默認初始化(0或null)----->顯示初始化(本來有值的)----->構造代碼快(對象)------>構造函數(有參數的話賦值)
 * 
 * 
 *   Person p = new Person("張三",4);
 * 此句話執行順序:
 * 1、因爲new用到了Person.class文件,所以首先把類加載到堆內存中,開闢空間,並且運行static靜態代碼塊
 * 2、然後屬性進行默認初始化,也就是0或者null,age=0,
 * 3、再次屬性進行顯示初始化,也就是age=3,
 * 4、因爲創建了對象,所以調用了構造代碼塊,記住,構造代碼塊是所有對象被創建時都會調用的,而構造函數只是針對特定對象而被調用
 * 5、最後調用了構造函數,並傳入參數進行賦值操作"張三",4
 * 6、將內存地址賦給對象P
 * */

public class Static_code {
	public static void main(String[] args) {
		Code.show();
	}
		
	static{
		System.out.println("b");
	}
}

class Code{
	static{
		System.out.println("a");
	}
	
	public  static void show(){
		System.out.println("c");
	}
}
 

---------------------- ASP.Net+Android+IOS開發.Net培訓、期待與您交流! ----------------------詳細請查看:http://edu.csdn.net 

 

發佈了35 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章