Java基礎面向對象

Java基礎第七天


面向對象思想

類與對象及其使用

對象的內存圖

成員變量和局部變量的區別

匿名對象

封裝(private)

this關鍵字

構造方法

static關鍵字

面向對象思想引入

  前面我們講過數組,當有多個數組都需要遍歷時,我們可以將遍歷的代碼封裝到方法中,需要遍歷時,就調用相應的方法即可,提高代碼的複用性。在對數組遍歷的基礎上繼續增加需求,比如獲取最值,數值逆序等,同樣需要將這些功能封裝到相應的方法中。這樣繼續封裝會發現方法越來越多,於是就想能不能將這些方法繼續進行封裝呢?通過前面的講解我們知道類是可以存放方法的,所以,我們就考慮使用類封裝來這多個方法,將來再做數組的操作時,不用去找具體的方法,先找到這個類,然後使用這個類中的方法。這就是面向對象思想的編程方式。


面向過程思想概述

  我們來回想一下,這幾天我們完成一個需求的步驟:首先是搞清楚我們要做什麼,然後在分析怎麼做,最後我們再代碼體現。一步一步去實現,而具體的每一步都需要我們去實現和操作。這些步驟相互調用和協作,完成我們的需求。

 

在上面的每一個具體步驟中我們都是參與者,並且需要面對具體的每一個步驟和過程,這就是面向過程最直接的體現。

 

  那麼什麼是面向過程開發呢? 面向過程開發,其實就是面向着具體的每一個步驟和過程,把每一個步驟和過程完成,然後由這些功能方法相互調用,完成需求。

面向過程的代表語言:C語言

 

面向對象思想概述

  當需求單一,或者簡單時,我們一步一步去操作沒問題,並且效率也挺高。可隨着需求的更改,功能的增多,發現需要面對每一個步驟很麻煩了,這時就開始思索,能不能把這些步驟和功能在進行封裝,封裝時根據不同的功能,進行不同的封裝,功能類似的封裝在一起。這樣結構就清晰了很多。用的時候,找到對應的類就可以了。這就是面向對象的思想。接下來我們看看面向對象到底是什麼?


1:面向對象思想

面向對象是基於面向過程的編程思想。


面向過程:強調的是每一個功能的步驟

面向對象:強調的是對象,然後由對象去調用功能

2:面向對象的思想特點

A:是一種更符合我們思想習慣的思想

B:可以將複雜的事情簡單化

C:將我們從執行者變成了指揮者


舉例:

買電腦:

面向過程:我的瞭解電腦--瞭解我自己的需求--找對應的參數信息--去中關村買電腦--討價還價--買回電腦

面向對象:我知道我要買電腦 -- 班長去給我買 -- 班長就買回來了

洗衣服:

面向過程:把衣服脫下--找一個盆--放點洗衣粉--加點水--把衣服扔進去--搓一搓--清洗衣服--擰乾--晾起來

面向對象:把衣服脫下--打開全自動洗衣機--扔進去--一鍵即可--晾起來

吃飯:

面向過程:去超市買菜--摘菜--洗菜--切菜--炒菜--盛起來--

面向對象:上飯店吃飯,你--服務員(點菜)--廚師(做菜)--服務員(端菜)--


家常事物,買洗衣機和去飯店太不划算了,所以,找個對象。

 

萬事萬物皆對象

面向過程思想和麪向對象思想的代碼舉例

把大象裝進冰箱

 

 

面向過程:

動作有哪些呢?

A:打開冰箱門

B:裝進大象

C:關閉冰箱門


代碼體現;

class Demo {

public static void main(String[] args) {

/*

System.out.println("打開冰箱門");

//打開冰箱門的東西,我現在僅僅是爲了演示,就寫了一個輸出語句

//其實,它可能需要做很多操作。

//這個時候代碼就比較多一些了

//假設我要多次打開冰箱門,

//代碼一多,每次都寫一遍,麻煩不

//我們就應該用方法改進


System.out.println("裝進大象");

System.out.println("關閉冰箱門");

*/


//寫了方法以後,調用就改變了

open();

in();

close();

}


public static void open() {

System.out.println("打開冰箱門");

}


public static void in() {

System.out.println("裝進大象");

}


public static void close() {

System.out.println("關閉冰箱門");

}

}


面向對象:

我們怎麼才能更符合面向對象思想呢?

A:有哪些類呢?

B:每個類有哪些東西呢?

C:類與類直接的關係是什麼呢?


把大象裝進冰箱的分析? (如何分析有哪些類呢?UML。名詞提取法。)

A:有哪些類呢?

大象

冰箱

Demo

B:每個類有哪些東西呢?

大象:

進去

冰箱:

開門

關門

Demo:

main方法

C:類與類直接的關係是什麼呢?

Demo中使用大象和冰箱類的功能。


代碼體現:

class 大象 {

public static void in() {

System.out.println("裝進大象");

}

}


class 冰箱 {

public static void open() {

System.out.println("打開冰箱門");

}


public static void close() {

System.out.println("關閉冰箱門");

}

}


class Demo {

public static void main(String[] args) {

冰箱調用開門

大象調用進去

冰箱調用關門

}

}

 

 

面向對象開發,設計,特徵

 

面向對象開發

就是不斷的創建對象,使用對象,指揮對象做事情

面向對象設計

其實就是在管理和維護對象之間的關係

面向對象特徵

封裝(encapsulation)

繼承(inheritance)

多態(polymorphism)

 

 

類與對象關係

  我們學習編程語言,就是爲了模擬現實世界的事物,實現信息化。比如:去超市買東西的計費系統,去銀行辦業務的系統。

 

我們如何表示一個現實世界事物呢:

  屬性  就是該事物的描述信息

  行爲  就是該事物能夠做什麼

  舉例:學生事物

 

 

現實世界中是如何描述一個事物的呢?

舉例:學生

姓名,年齡,性別...

學習,吃飯,睡覺


屬性:該事物的描述信息

行爲:該事物能夠做什麼


我們學習編程語言,是爲了模擬現實世界的事物的。

而我們學習的編程語言Java中最基本的單位是:

所以,我們就應該把事物通過來體現出來:

由此,我們就得到了現實世界事物的對應關係:

 

事物:類:

屬性成員變量

行爲成員方法



類:是一組相關的屬性和行爲的集合。是一個抽象的概念

對象:是該類事物的具體表現形式。具體存在的個體。

 

舉例:

學生:類

班長:對象

 

 

類與對象的關係如圖

wKioL1hfeaHDicGTAABscFIMiW0802.png


類的定義

 

現實世界的事物

屬性人的身高,體重等

行爲人可以學習,吃飯等

 

Java中用class描述事物也是如此

成員變量就是事物的屬性

成員方法就是事物的行爲

定義類其實就是定義類的成員(成員變量和成員方法)

 

 

/*

事物:

屬性事物的信息描述

行爲事物的功能


類:

成員變量事物的屬性

成員方法事物的行爲


定義一個類,其實就是定義該類的成員變量和成員方法。


案例:我們來完成一個學生類的定義。


學生事物:

屬性:姓名,年齡,地址...

行爲:學習,吃飯,睡覺...


把事物要轉換爲對應的類:


學生類:

成員變量:姓名,年齡,地址...

成員方法:學習,吃飯,睡覺...


成員變量:和以前變量的定義是一樣的格式,但是位置不同,在類中方法外

成員方法:和以前的方法定義是一樣的格式,但是今天把static先去掉。


首先我們應該定義一個類,然後完成類的成員。

*/

class  Student
{
	//定義變量(成員變量)
	String name;
	//性別 男1 女0
	int sex;
	//年齡
	int age;
	//地址
	String address;

	//學習的方法
	public void study()
	{
		System.out.println("學生愛學習");
	}
	//睡覺的方法
	public void sleep()
	{
		System.out.println("學習累了要睡覺");
	}
	//吃飯的方法
	public void eat()
	{
		System.out.println("學習餓了,要吃飯");
	}
}


/*

手機事物:

屬性:品牌,價格,顏色...

行爲:打電話,發短信,玩遊戲...


手機類:

成員變量:品牌,價格,顏色

成員方法:打電話,發短信,玩遊戲

*/

class Phone 
{
	//變量(成員變量)
	//品牌
	String brand;
	//價格
	int price;
	//顏色
	String color;

	//打電話的方法
	public void call(String name)
	{
		System.out.println("給"+name+"打電話");
	}
	//發短信的方法
	public void send(String name)
	{
		System.out.println("給"+name+"發短信");
	}
	//玩遊戲的方法
	public void game()
	{
        System.out.println("玩遊戲");
	}
}

學生類(講解)

如何定義

   按照事物到類的過程一步步分析

如何使用

創建對象:

類名 對象名 = new 類名();

對象名.成員變量

對象名.成員方法

 

/*

在一個java文件中寫兩個類:一個基本的類,一個測試類。

注意:文件名稱和測試類名稱一致。


如何使用呢?

創建對象使用。


如何創建對象呢?

格式:類名 對象名 = new 類名();


如何使用成員變量呢?

對象名.變量名

如何使用成員方法呢?

對象名.方法名(...)

*/

class  Student
{
	//定義變量(成員變量)
	String name;
	//性別 男1 女0
	int sex;
	//年齡
	int age;
	//地址
	String address;

	//學習的方法
	public void study()
	{
		System.out.println("學生愛學習");
	}
	//睡覺的方法
	public void sleep()
	{
		System.out.println("學習累了要睡覺");
	}
	//吃飯的方法
	public void eat()
	{
		System.out.println("學習餓了,要吃飯");
	}
}
class StudentDemo
{
	public static void main(String[] args)
	{
		//創建對象:類名 對象名 = new 類名();
		Student banzhang = new Student();
		//調用:對象名.成員變量
		//       對象名.成員方法
		System.out.println(banzhang.name);
		System.out.println(banzhang.age);
		System.out.println(banzhang.address);

		banzhang.study();
		banzhang.sleep();
		banzhang.eat();

		Student s = new Student();//?創建對象
	}
}
 
/*
手機類的測試
*/
class Phone
{
	String brand;
	int price;
	String color;
	public void call(String name,int num)
	{
		System.out.println("給"+name+"打電話"+num);
	}
	public void send(String name)
	{
		System.out.println("給"+name+"發短信");
	}
	public void game()
	{
		System.out.println("打遊戲");
	}
}

class PhoneDemo
{
	public static void main(String[] args) 
	{
		Phone iPhone = new Phone();
		System.out.println(iPhone.brand);
		System.out.println(iPhone.price);
		System.out.println(iPhone.color);

        iPhone.game();
		iPhone.call("家裏",1283083);
		iPhone.send("家裏");
		
	}
}

1個對象的內存圖

一個對象的基本初始化過程

wKioL1hffCuzcJcdAAC9KJQRBZk872.png

2個對象的內存圖

wKioL1hffGHBicbuAAD7jYTIwac112.png

3個對象的內存圖

其中有兩個引用指向同一個對象

wKiom1hffJLSNUm2AAC7Lllzgkk743.png

成員變量和局部變量的區別

在類中的位置不同

 成員變量 類中方法外

 局部變量 方法內或者方法聲明上

 

在內存中的位置不同

 成員變量 堆內存

 局部變量 棧內

 

生命週期不同

成員變量 隨着對象的存在而存在,隨着對象的消失而消失

局部變量 隨着方法的調用而存在,隨着方法的調用完畢而消失

 

初始化值不同

成員變量 有默認的初始化值

局部變量 沒有默認的初始化值,必須先定義,賦值,才能使用。

 

/*

成員變量和局部變量的區別?

A:在類中的位置不同

成員變量:在類中方法外

局部變量:在方法定義中或者方法聲明上

B:在內存中的位置不同

成員變量:在堆內存

局部變量:在棧內存

C:生命週期不同

成員變量:隨着對象的創建而存在,隨着對象的消失而消失

局部變量:隨着方法的調用而存在,隨着方法的調用完畢而消失

D:初始化值不同

成員變量:有默認初始化值

局部變量:沒有默認初始化值,必須定義,賦值,然後才能使用。


注意事項:

局部變量名稱可以和成員變量名稱一樣,在方法中使用的時候,採用的是就近原則。

*/

class Varialbe 
{ 

	int a ;//成員變量

	public  void show(){
	  //錯誤: 可能尚未初始化變量i
	   //int i ;

	   int i = 0 ;//局部變量

	   System.out.println(i);
	}
}

class VariableDemo
{

	public static void main(String[] args){

     Varialbe  v = new Varialbe();
	 v.show();

	 System.out.println(v.a);
	   
	}
}

形式參數問題

基本類型作爲形式參數

引用類型作爲形式參數

 

/*

形式參數的問題:

基本類型:形式參數的改變不影響實際參數

引用類型:形式參數的改變直接影響實際參數

*/

class ZhengShuJiSuan
{
	public void sum(int a,int b)
	{
		int c = a + b;
		System.out.println(c);
	}
}

class ShuZuJiSuan
{
	public void printArr(int[] arr)
	{
        int length = arr.length;
		System.out.println("length="+length);
	}
}

class LeiJiSuan
{
	public void printMethod(Student student)
	{
		student.study();

		student.eat();
	}
}

class Student
{
	public void study()
	{
		System.out.println("我要好好學習");
	}
	public void eat()
	{
		System.out.println("我要好好吃飯");
	}
}

class TestXingCan 
{
	public static void main(String[] args) 
	{
		ZhengShuJiSuan zsjs = new ZhengShuJiSuan();
		zsjs.sum(3,5);

		ShuZuJiSuan szjs = new ShuZuJiSuan();
		int[] array = new int[5];
		szjs.printArr(array);

		LeiJiSuan ljs = new LeiJiSuan();
		Student student = new Student();
		ljs.printMethod(student);

		System.out.println("Hello World!");
	}
}

匿名對象

匿名對象:就是沒有名字的對象。【面試】

  是對象的一種簡化表示形式

匿名對象的兩種使用情況

  對象調用方法僅僅一次的時候

  作爲實際參數傳遞

 

/*

匿名對象:就是沒有名字的對象。


匿名對象的應用場景:

A:調用方法,僅僅只調用一次的時候。

注意:調用多次的時候,不適合。

那麼,這種匿名調用有什麼好處嗎?

有,匿名對象調用完畢就是垃圾。可以被垃圾回收器回收。

B:匿名對象可以作爲實際參數傳遞

*/

class Student
{
	public void show()
	{
		System.out.println("我愛學習");
	}
}

class LeiMethod
{
	public void print(Student s)
	{
        s.show();
	}
}


class NoNameDemo 
{
	public static void main(String[] args) 
	{
		Student student = new Student();
		student.show();//第一個

		new Student().show();//第二個

		new LeiMethod().print(new Student());//第三個

		//Student student = new Student();
		new LeiMethod.print(new Student());
		//System.out.println("Hello World!");
	}
}

封裝概述

封裝概述

  是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。

好處:

   隱藏實現細節,提供公共的訪問方式

   提高了代碼的複用性

   提高安全性。

封裝原則

   將不需要對外提供的內容都隱藏起來。

   把屬性隱藏,提供公共方法對其訪問。

 

/*

定義一個學生類:

成員變量:name,age

成員方法:show()方法


我們在使用這個案例的過程中,發現了一個問題:

通過對象去給成員變量賦值,可以賦值一些非法的數據。

這是不合理的。

應該是這個樣子的:在賦值之前,先對數據進行判斷。

判斷到底在哪裏做比較合適呢?

StudentDemo類是一個測試類,測試類一般只創建對象,調用方法。

所以,這個判斷應該定義在Student類中。

而我們在成員變量的位置可不可以進行數據判斷呢?

是不可以的,因爲做數據校驗,必須要依靠一些邏輯語句。

邏輯語句是應該定義在方法中的,所以,我們最終決定在Student類中提供一個方法

來對數據進行校驗。


按照我們前面的分析,我們給出了一個方法進行校驗。

但是呢,它偏偏不調用方法來賦值,還是直接賦值了,

這樣我們的方法就沒有起到作用。

我就應該要求你必須使用我的方法,而不能直接調用成員變量賦值。

怎麼去強制要求不能直接使用成員變量呢?

針對這種情況,Java就提供了一個關鍵字 private


private:私有的。可以修飾成員變量和成員方法。

注意:被private修飾的成員只能在本類中訪問。


其實我講到現在講解的是一個封裝的思想。

封裝:是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。

*/


private關鍵字

private關鍵字

是一個權限修飾符。

可以修飾成員(成員變量和成員方法)

被private修飾的成員只在本類中才能訪問。

 

private最常見的應用:

把成員變量用private修飾

提供對應的getXxx()/setXxx()方法

一個標準的案例的使用

/*

private:

是一個權限修飾符

可以修飾成員變量和成員方法

被其修飾的成員只能在本類中被訪問

*/

class Demo
{
	private int num = 10;

	public int getNum()
	{
		return num;
	}
	public void setNum(int a)
	{
		if(a < 0 || a > 100){
			System.out.println("我是有底線的");
		}else{
			num = a;
		}
	}
	private void study()
	{
		System.out.println("我要學習");
	}
	public void method()
	{
		study();
	}
}


class PrivateDemo 
{
	public static void main(String[] args) 
	{
		Demo demo = new Demo();
		demo.setNum(120);

		System.out.println(demo.getNum());

		demo.method();
	}
}

正常Student類測試

/*

封裝和private的應用:

A:把成員變量用private修飾

B:提高對應的getXxx()setXxx()方法

*/

//定義學生類
class Student {
	//姓名
	private String name;
	//年齡
	private int age;
	
	//姓名獲取值
	public String getName() {
		return name;
	}
	
	//姓名設置值
	public void setName(String n) {
		name = n;
	}
	
	//年齡獲取值
	public int getAge() {
		return age;
	}
	
	//年齡賦值
	public void setAge(int a) {
		age = a;
	}
}

//測試類
class StudentTest {
	public static void main(String[] args) {
		//創建學生對象
		Student s = new Student();
		
		//使用成員變量
		//錯誤:被私有修飾了,外界不能直接訪問了
		//System.out.println(s.name+"---"+s.age);
		System.out.println(s.getName()+"---"+s.getAge());
		
		//給成員變量賦值
		//s.name = "林青霞";
		//s.age = 27;
		//通過方法給賦值
		s.setName("林青霞");
		s.setAge(27);
		System.out.println(s.getName()+"---"+s.getAge());
	}
}

This使用

 

this:代表所在類的對象引用

記住:

方法被哪個對象調用,this就代表那個對象

 

什麼時候使用this?

   局部變量隱藏成員變量

   其他用法後面和super一起講解

 

案例:

 

/*

我們曾經曰:起名字要做到見名知意。


this:是當前類的對象引用。簡單的記,它就代表當前類的一個對象。


注意:誰調用這個方法,在該方法內部的this就代表誰。


this的場景:

解決局部變量隱藏成員變量

*/

class Student
{
	private String name;
	private String address;
	private int age;
	/**
	構造方法
	*/
	public Student()
	{

	}

	public Student(String name)
	{
		this.name = name;
	}
	public Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}

	/**
	成員方法,獲取name值
	*/
	public String getName()
	{
		return name;
	}

}


class ConstructDemo 
{
	public static void main(String[] args) 
	{
        Student student = new Student("林青霞");
		System.out.println(student.getName());
        Student student1 = new Student("林青霞",18);
		System.out.println(student1.getName());
	}
}


構造方法

 

構造方法作用概述

 給對象的數據進行初始化

 

構造方法格式

   方法名與類名相同

   沒有返回值類型,連void都沒有

   沒有具體的返回值

構造方法注意事項

   如果你不提供構造方法,系統會給出默認構造方法

   如果你提供了構造方法,系統將不再提供

   構造方法也是可以重載的

 

 

 

/*

構造方法:

給對象的數據進行初始化

 

格式:

A:方法名與類名相同

B:沒有返回值類型,連void都沒有

C:沒有具體的返回值

*/


方法構造二

/*

我們一直在使用構造方法,但是,我們確沒有定義構造方法,用的是哪裏來的呢?


構造方法的注意事項:

A:如果我們沒有給出構造方法,系統將自動提供一個無參構造方法。

B:如果我們給出了構造方法,系統將不再提供默認的無參構造方法。

注意:這個時候,如果我們還想使用無參構造方法,就必須自己給出。建議永遠自己給出無參構造方法


給成員變量賦值有兩種方式:

A:setXxx()

B:構造方法

*/


類的成員方法

成員方法其實就是我們前面講過的方法

方法具體劃分

 根據返回值

    有明確返回值方法

    返回void類型的方法

根據形式參數

    無參方法

帶參方法

 

 

 

案例:

/*

類的組成:成員變量,成員方法

今天我們又加入了一個新的成員:構造方法。

以後再提類的組成:

成員變量

構造方法

成員方法

根據返回值:

void類型

非void類型

形式參數:

空參方法

非空參方法

*/

class Student {
	public String getString() {
		return "helloworld";
	}

	public void show() {
		System.out.println("show");
	}
	
	public void method(String name) {
		System.out.println(name);
	}
	
	public String function(String s1,String s2) {
		return s1+s2;
	}
}

class StudentDemo {
	public static void main(String[] args) {
		//創建對象
		Student s = new Student();
		
		//調用無參無返回值方法
		s.show();
		
		//調用無參有返回值方法
		String result = s.getString();
		System.out.println(result);
		
		//調用帶參無返回值的方法
		s.method("林青霞");
		
		//調用帶參帶返回值的方法
		String result2 = s.function("hello","world");
		System.out.println(result2);
	}
}

 

一個基本類的標準代碼寫法

 成員變量

 構造方法

      無參構造方法

      帶參構造方法

成員方法

   getXxx()

   setXxx()

 

給成員變量賦值的方式

  無參構造方法+setXxx()

   帶參構造方法

 

一個標準學生代碼以及測試:

/*

一個標準代碼的最終版。


學生類:

成員變量:

name,age

構造方法:

無參,帶兩個參

成員方法:

getXxx()/setXxx()

show():輸出該類的所有成員變量值


給成員變量賦值:

A:setXxx()方法

B:構造方法


輸出成員變量值的方式:

A:通過getXxx()分別獲取然後拼接

B:通過調用show()方法搞定

*/

class Student {
	//姓名
	private String name;
	//年齡
	private int age;
	
	//構造方法
	public Student() {
	}
	
	public Student(String name,int age) {
		this.name = name;
		this.age = 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;
	}
	
	//輸出所有的成員變量值
	public void show() {
		System.out.println(name+"---"+age);
	}
}

//測試類
class StudentTest {
	public static void main(String[] args) {
		//方式1給成員變量賦值
		//無參構造+setXxx()
		Student s1 = new Student();
		s1.setName("林青霞");
		s1.setAge(27);
		//輸出值
		System.out.println(s1.getName()+"---"+s1.getAge());
		s1.show();
		System.out.println("----------------------------");
		
		//方式2給成員變量賦值
		Student s2 = new Student("劉意",30);
		System.out.println(s2.getName()+"---"+s2.getAge());
		s2.show();
	}
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章