一.面向?qū)ο笏枷?/h3>
(一)面向?qū)ο蟮母拍睿?/h4>
Java語言是一種的程序設(shè)計語言,而面向?qū)ο笏枷胧且环N程序設(shè)計思想黄选,我們在面向?qū)ο笏枷氲闹敢掠褂肑ava語言去設(shè)計、開發(fā)計算機(jī)程序办陷。 這里的對象泛指現(xiàn)實中一切事物貌夕,每種事物都具備自己的和。面向?qū)ο笏枷刖褪窃谟嬎銠C(jī)程序設(shè)計過程中民镜,參照現(xiàn)實中事物啡专,將事物的屬性特征、行為特征抽象出來制圈,描述成計算機(jī)事件的設(shè)計思想们童。 它區(qū)別于面向過程思想,強(qiáng)調(diào)的是通過調(diào)用對象的行為來實現(xiàn)功能鲸鹦,而不是自己一步一步的去操作實現(xiàn)慧库。
- 面向過程:當(dāng)需要實現(xiàn)一個功能的時候,每一個 具體的步驟都要親力親為馋嗜,詳細(xì)處理每一個細(xì)節(jié)齐板。
- 面向?qū)ο?當(dāng)需要實現(xiàn)一個功能的時候,不關(guān)心具體的步驟葛菇,而是找一個已經(jīng)具有 該功能的人甘磨,來幫我做事兒。
舉例:洗衣服
- 面向過程:把衣服脫下來-->找一個盆-->放點洗衣粉-->加點水-> 浸泡10分鐘-->揉一揉-->清洗衣服-->擰干-->晾起來
- 面向?qū)ο螅喊岩路撓聛?->打開全自動洗衣機(jī)-->扔衣服-->按鈕-->晾起來
(二)面向?qū)ο蟮奶攸c:
面向?qū)ο蟮恼Z言中眯停,包含了三大基本特征宽档,即封裝、繼承和多態(tài)庵朝。
二.類與對象
(一)什么是類
類:是一組相關(guān)屬性和行為的集合吗冤。可以看成是一類事物的模板九府,使用事物的屬性特征和行為特征來描述該類事物椎瘟。
- 屬性:就是該事物的狀態(tài)信息。
- 行為:就是該事物能夠做什么侄旬。
舉例:小貓肺蔚。
- 屬性:名字、體重儡羔、年齡宣羊、顏色璧诵。
- 行為:走、跑仇冯、叫之宿。
(二)什么是對象
對象:是一類事物的具體體現(xiàn)。對象是類的一個實例苛坚,必然具備該類事物的屬性和行為比被。
舉例:小貓。
- 屬性:湯姆泼舱、5kg等缀、2、白色娇昙。
- 行為:溜墻根走尺迂、蹦跶跑、喵喵叫冒掌。
(三)類與對象的關(guān)系
- 類是對一類事物的描述枪狂,是抽象的。
- 對象是一類事物的實例宋渔,是具體的。
- 類是對象的模板辜限,對象是類的實體皇拣。
(四)類的定義
1.事物與類的對比
現(xiàn)實世界的一類事物:
- 屬性:事物的狀態(tài)信息。
- 行為:事物能夠做什么薄嫡。
Java中用類(class)描述事物也是如此:
- 成員變量:對應(yīng)事物的屬性 氧急。
- 成員方法:對應(yīng)事物的行為。
2.類的定義格式:
public class ClassName {
//成員變量
//成員方法
}
- 定義類:就是定義類的成員毫深,包括成員變量和成員方法吩坝。
- 成員變量:和以前定義變量幾乎是一樣的。只不過位置發(fā)生了改變哑蔫。在類中钉寝,方法外。
- 成員方法:和以前定義方法幾乎是一樣的闸迷。只不過把static去掉嵌纲。
代碼:
public class Student {
// 成員變量
String name; // 姓名
int age; // 年齡
// 成員方法
public void study() {
// 學(xué)習(xí)的方法
System.out.println("好好學(xué)習(xí),天天向上!");
}
public void eat() {
System.out.println("吃飯飯~");
}
}
(五)對象的使用
1.對象的使用格式
通常情況下,一個類并不能直接使用腥沽,需要根據(jù)類創(chuàng)建一個對象逮走,才能使用。
(1) 導(dǎo)包:也就是指出需要使用的類今阳,在什么位置师溅。
import 包名稱.類名稱;
import cn.cxy.demo04.Student ;
對于和當(dāng)前類屬于同-一個包的情況茅信,可以省略導(dǎo)包語句不寫。
(2) 創(chuàng)建:
類名稱 對象名= new 類名稱();
Student stu = new Student();
(3) 使用(分為兩種情況):
- 使用成員變量:
對象名.成員變量名
- 使用成員方法:
對象名.成員方法名(參數(shù))
代碼:
public class StudentTest1 {
public static void main(String[] args) {
// 創(chuàng)建對象格式:類名 對象名 = new 類名();
Student student = new Student();
System.out.println("student:" + student);
// 直接輸出成員變量值
System.out.println("姓名:" + student.name); // null
System.out.println("年齡:" + student.age); // 0
// 給成員變量賦值
student.name = "趙麗穎";
student.age = 20;
// 再次輸出成員變量的值
System.out.println("姓名:" + student.name); // 趙麗穎
System.out.println("年齡:" + student.age); // 20
// 調(diào)用成員變量方法
student.study(); // 好好學(xué)習(xí),天天向上!
student.eat(); // 吃飯飯~
}
}
運(yùn)行結(jié)果:
2.成員變量的默認(rèn)值
如果成員變量沒有進(jìn)行賦值墓臭,那么將會有一個默認(rèn)值蘸鲸,規(guī)則和數(shù)組一樣。
數(shù)據(jù)類型 默認(rèn)值
基本類型 整數(shù)(byte起便,short棚贾,int,long) 0
浮點數(shù)(float榆综,double) 0.0
字符(char) '\u0000'
布爾(boolean) false
引用類型 數(shù)組妙痹,類,接口 null
三.對象內(nèi)存圖
(一)只有一個對象的內(nèi)存圖
代碼:
Phone.java
public class Phone {
// 成員變量
String brand; // 品牌
double price; //價格
String color; // 顏色
// 成員方法
public void call(String who) {
System.out.println("給" + who + "打電話");
}
public void sendMessage() {
System.out.println("群發(fā)短信");
}
}
PhoneTest1.java
public class PhoneTest1 {
public static void main(String[] args) {
// 根據(jù)Phone類,創(chuàng)建一個名為one的對象
// 格式:類名稱 對象名 = new 類名稱();
Phone one = new Phone();
System.out.println(one.brand); // null
System.out.println(one.price); // 0.0
System.out.println(one.color); // null
System.out.println("==============");
one.brand = "蘋果";
one.price = 8388.0;
one.color = "黑色";
System.out.println(one.brand); // 蘋果
System.out.println(one.price); // 8388.0
System.out.println(one.color); // 黑色
System.out.println("==============");
one.call("喬布斯"); // 給喬布斯打電話
one.sendMessage(); // 群發(fā)短信
}
}
運(yùn)行結(jié)果:
內(nèi)存圖
(二)兩個對象使用同一個方法的內(nèi)存圖
代碼:
PhoneTest2.java
public class PhoneTest2 {
public static void main(String[] args) {
// 根據(jù)Phone類,創(chuàng)建一個名為one的對象
// 格式:類名稱 對象名 = new 類名稱();
Phone one = new Phone();
System.out.println(one.brand); // null
System.out.println(one.price); // 0.0
System.out.println(one.color); // null
System.out.println("==============");
one.brand = "蘋果";
one.price = 8388.0;
one.color = "黑色";
System.out.println(one.brand); // 蘋果
System.out.println(one.price); // 8388.0
System.out.println(one.color); // 黑色
System.out.println("==============");
one.call("喬布斯"); // 給喬布斯打電話
one.sendMessage(); // 群發(fā)短信
System.out.println("============================");
Phone two = new Phone();
System.out.println(two.brand); // null
System.out.println(two.price); // 0.0
System.out.println(two.color); // null
System.out.println("==============");
two.brand = "三星";
two.price = 5999.0;
two.color = "藍(lán)色";
System.out.println(two.brand); // 三星
System.out.println(two.price); // 5999.0
System.out.println(two.color); // 藍(lán)色
System.out.println("==============");
two.call("歐巴"); // 給歐巴打電話
two.sendMessage(); // 群發(fā)短信
}
}
運(yùn)行結(jié)果:
內(nèi)存圖
(三)兩個引用指向同一個對象的內(nèi)存圖
代碼:
PhoneSame.java
public class PhoneSame {
public static void main(String[] args) {
// 根據(jù)Phone類,創(chuàng)建一個名為one的對象
// 格式:類名稱 對象名 = new 類名稱();
Phone one = new Phone();
System.out.println(one.brand); // null
System.out.println(one.price); // 0.0
System.out.println(one.color); // null
System.out.println("==============");
one.brand = "蘋果";
one.price = 8388.0;
one.color = "黑色";
System.out.println(one.brand); // 蘋果
System.out.println(one.price); // 8388.0
System.out.println(one.color); // 黑色
System.out.println("==============");
one.call("喬布斯"); // 給喬布斯打電話
one.sendMessage(); // 群發(fā)短信
System.out.println("============================");
Phone two = new Phone();
System.out.println(two.brand); // null
System.out.println(two.price); // 0.0
System.out.println(two.color); // null
System.out.println("==============");
two.brand = "三星";
two.price = 5999.0;
two.color = "藍(lán)色";
System.out.println(two.brand); // 三星
System.out.println(two.price); // 5999.0
System.out.println(two.color); // 藍(lán)色
System.out.println("==============");
two.call("歐巴"); // 給歐巴打電話
two.sendMessage(); // 群發(fā)短信
}
}
運(yùn)行結(jié)果:
內(nèi)存圖:
(四)使用對象類型作為方法的參數(shù)的內(nèi)存圖
- 當(dāng)一個對象作為參數(shù),傳遞到方法當(dāng)中時,實際上傳遞進(jìn)去的是對象的地址值。
PhoneParam.java
代碼:
public class PhoneParam {
public static void main(String[] args) {
Phone one = new Phone();
one.brand = "蘋果";
one.price = 8388.0;
one.color = "土豪金";
method(one); // 傳遞進(jìn)去的參數(shù)其實就是地址值
}
public static void method(Phone param) {
System.out.println(param.brand); // 蘋果
System.out.println(param.price); // 8388.0
System.out.println(param.color); // 土豪金
}
}
運(yùn)行結(jié)果:
內(nèi)存圖
(五)使用對象類型作為方法的返回值的內(nèi)存圖
- 當(dāng)使用一個對象類型作為方法的返回值時:返回值其實就是對象的地址值。
PhoneReturn.java
代碼:
public class PhoneReturn {
public static void main(String[] args) {
Phone two = getPhone();
System.out.println(two.brand); // 蘋果
System.out.println(two.price); // 8388.0
System.out.println(two.color); // 玫瑰金
}
public static Phone getPhone() {
Phone one = new Phone();
one.brand = "蘋果";
one.price = 8388.0;
one.color = "玫瑰金";
return one;
}
}
運(yùn)行結(jié)果:
內(nèi)存圖
四.成員變量和局部變量區(qū)別
(一)什么是成員變量和局部變量
變量根據(jù)定義位置的不同载萌,我們給變量起了不同的名字将饺。如下圖所示:
(二)成員變量和局部變量區(qū)別
1.在類中的位置不同
- 成員變量:在方法的外部,直接寫在類當(dāng)中峦嗤。
- 局部變量:在方法的內(nèi)部或者在方法的聲明上(形式參數(shù))。
2.作用范圍不一樣
- 成員變量:整個類全都可以通用。
- 局部變量:只有方法當(dāng)中才可以使用吧秕,出了方法就不能再用。
3.初始化值的不同
- 成員變量:有默認(rèn)值迹炼。
- 局部變量:沒有默認(rèn)值砸彬,如果要想使用,必須手動進(jìn)行賦值斯入。
4.在內(nèi)存中的位置不同
- 成員變量:位于堆內(nèi)存砂碉。
- 局部變量:位于棧內(nèi)存。
5.生命周期不同
- 成員變量:隨著對象創(chuàng)建而誕生刻两,隨著對象被垃圾回收而消失增蹭。
- 局部變量:隨著方法進(jìn)棧而誕生,隨著方法出棧而消失磅摹。
五.封裝
(一)封裝概述
面向?qū)ο缶幊陶Z言是對客觀世界的模擬滋迈,客觀世界里都是隱藏在對象內(nèi)部的,外界無法和户誓。封裝可以被認(rèn)為是一個保護(hù)屏障杀怠,防止該類的代碼和數(shù)據(jù)被其他類。要訪問該類的數(shù)據(jù)厅克,必須通過赔退。適當(dāng)?shù)姆庋b可以讓代碼更容易理解與維護(hù),也加強(qiáng)了代碼的安全性。
(二)封裝的原則
將屬性隱藏起來硕旗,若需要訪問某個屬性窗骑,提供公共方法對其訪問。
(三)封裝的步驟
- 使用 private 關(guān)鍵字來修飾成員變量漆枚。
- 對需要訪問的成員變量创译,提供對應(yīng)的一對 getXxx 方法 、 setXxx 方法墙基。
(四)封裝的操作—private關(guān)鍵字
1.private的含義
- private是一個權(quán)限修飾符软族,代表最小權(quán)限。
- 可以修飾成員變量和成員方法残制。
- 被private修飾后的成員變量和成員方法立砸,只在本類中才能訪問。
2.private的使用格式
private 數(shù)據(jù)類型 變量名;
使用 private 修飾成員變量
代碼:
public class Student {
private String name;
private int age;
}
3.間接訪問private成員變量
間接訪問private成員變量初茶,就是定義一對兒Getter/Setter方法
必須叫setXxx或者是getXxx
命名規(guī)則:
- 對于Getter來說颗祝,不能有參數(shù),返回值類型和成員變量對應(yīng)恼布。
- 對于Setter來說螺戳,不能有返回值,參數(shù)類型和成員變量對應(yīng)折汞。
對于基本類型當(dāng)中的boolean值倔幼,Getter方法一定要寫成isXxx的形式,而setXxx規(guī)則不變爽待。
代碼:
Student2.java
package cn.cxy.demo04;
public class Student2 {
private String name; //姓名
private int age; //年齡
private boolean male; //是不是男性
public String getName() {
return name;
}
public void setName(String str) {
name = str;
}
public int getAge() {
return age;
}
public void setAge(int num) {
age = num;
}
public boolean isMale() {
return male;
}
public void setMale(boolean b) {
male = b;
}
}
StudentTest2.java
public class StudentTest2 {
public static void main(String[] args) {
Student2 student = new Student2();
student.setName("鹿晗");
student.setAge(20);
student.setMale(true);
System.out.println("姓名: " + student.getName());
System.out.println("年齡: " + student.getAge());
System.out.println("是不是男性: " + student.isMale());
}
}
運(yùn)行結(jié)果:
(五)封裝的兩點優(yōu)化
1.this關(guān)鍵字
(1) 為什么要使用this關(guān)鍵字
我們發(fā)現(xiàn) setXxx 方法中的形參名字并不符合見名知意的規(guī)定损同,那么如果修改與成員變量名一致,是否就見名知意了呢堕伪?
代碼:
Person.java
public class Person {
String name; // 我自己的名字
// 參數(shù)who是對方的名字
// 成員變量name是自己的名字
public void sayHello(String name) {
// 錯誤寫法,成員變量被隱藏
System.out.println(name + ",你好.我是" + name);
}
}
PersonTest.java
public class PersonTest {
public static void main(String[] args) {
Person person = new Person();
person.name = "王健林";
person.sayHello("王思聰");
}
}
運(yùn)行結(jié)果:
當(dāng)方法的局部變量和類的成員變量重名的時候,根據(jù)“就近原則”,優(yōu)先使用局部變量栗菜。
由于形參變量名與成員變量名重名欠雌,導(dǎo)致成員變量名被隱藏,方法中的變量名疙筹,無法訪問到成員變量富俄,從而賦值失敗。所以而咆,我們只能使用this關(guān)鍵字霍比,來解決這個重名問題。
(2) this的含義
this代表所在類的當(dāng)前對象的引用(地址值)暴备,即對象自己的引用
方法被哪個對象調(diào)用悠瞬,方法中的this就代表那個對象。即誰在調(diào)用,this就代表誰浅妆。
(3) this使用格式:
this.成員變量名;
使用 this 修飾方法中的變量望迎,解決成員變量被隱藏的問題。
代碼:
Person.java
public class Person {
String name; // 我自己的名字
// 參數(shù)who是對方的名字
// 成員變量name是自己的名字
public void sayHello(String name) {
// 錯誤寫法,成員變量被隱藏
System.out.println(name + ",你好.我是" + this.name);
System.out.println(this);
}
PersonTest.java
public class PersonTest {
public static void main(String[] args) {
Person person = new Person();
person.name = "王健林";
person.sayHello("王思聰");
System.out.println(person);
}
}
運(yùn)行結(jié)果:
2.構(gòu)造方法
當(dāng)一個對象被創(chuàng)建時候凌外,構(gòu)造方法用來初始化該對象辩尊,給對象的成員變量賦初始值。
小貼士: 無論你與否自定義構(gòu)造方法康辑,所有的類都有構(gòu)造方法摄欲,因為Java自動提供了一個無參數(shù)構(gòu)造方法,一旦自己定義了構(gòu)造方法疮薇,Java自動提供的默認(rèn)無參數(shù)構(gòu)造方法就會失效胸墙。
(1) 構(gòu)造方法的定義格式
修飾符 構(gòu)造方法名(參數(shù)列表){
// 方法體
}
(2) 無參構(gòu)造方法與有參構(gòu)造方法
代碼:
Student3.java
public class Student3 {
// 成員變量
private String name;
private int age;
// 無參數(shù)的構(gòu)造方法
public Student3() {
System.out.println("無參構(gòu)造方法執(zhí)行啦!");
}
// 全參數(shù)的構(gòu)造方法
public Student3(String name, int age) {
System.out.println("全參構(gòu)造方法執(zhí)行啦!");
this.name = name;
this.age = age;
}
// Getter Setter
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;
}
}
StudentTest3.java
public class StudentTest3 {
public static void main(String[] args) {
Student3 student1 = new Student3(); // 無參構(gòu)造
System.out.println("================");
Student3 student2 = new Student3("趙麗穎", 20); // 全參構(gòu)造
System.out.println("姓名: " + student2.getName() + ",年齡: " + student2.getAge());
}
}
運(yùn)行結(jié)果:
注意事項:
- 構(gòu)造方法的名稱必須和所在的類名稱完全一樣,就連大小寫也要一樣惦辛。
- 構(gòu)造方法不要寫返回值類型劳秋,連void都不寫。
- 構(gòu)造方法不能return一個具體的返回值胖齐。
- 如果你不提供構(gòu)造方法玻淑,系統(tǒng)會給出無參數(shù)構(gòu)造方法。
- 如果你提供了構(gòu)造方法呀伙,系統(tǒng)將不再提供無參數(shù)構(gòu)造方法补履。
- 構(gòu)造方法也是可以進(jìn)行重載的。
六.標(biāo)準(zhǔn)類(JavaBean)
(一)什么是標(biāo)準(zhǔn)類
JavaBean 是 Java語言編寫類的一種標(biāo)準(zhǔn)規(guī)范剿另。符合 JavaBean 的類箫锤,要求類必須是具體的和公共的,并且具有無參數(shù)的構(gòu)造方法雨女,提供用來操作成員變量的 set 和 get 方法谚攒。
(二)標(biāo)準(zhǔn)類的組成
一個標(biāo)準(zhǔn)的類通常要擁有下面四個組成部分:
- 所有的成員變量都要使用private關(guān)鍵字修飾
- 為每一個成員變量編寫一對兒Getter/Setter方法
- 編寫一個無參數(shù)的構(gòu)造方法
- 編寫一個全參數(shù)的構(gòu)造方法
代碼:
StudentStandardClass.java
public class StudentStandardClass {
private String name; // 姓名
private int age; // 年齡
// 無參構(gòu)造方法
public StudentStandardClass() {
}
// 全參構(gòu)造方法
public StudentStandardClass(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;
}
}
StudentStandardTest.java
public class StudentStandardTest {
public static void main(String[] args) {
StudentStandardClass student1 = new StudentStandardClass();
student1.setName("迪麗熱巴");
student1.setAge(20);
System.out.println("姓名: " + student1.getName() + ", 年齡: " + student1.getAge());
System.out.println("======================");
StudentStandardClass student2 = new StudentStandardClass("古力娜扎",21);
System.out.println("姓名: " + student2.getName() + ", 年齡: " + student2.getAge());
}
}
運(yùn)行結(jié)果:
七.匿名對象
(一)概念
創(chuàng)建對象時,只有創(chuàng)建對象的語句氛堕,卻沒有把對象地址值賦值給某個變量馏臭。雖然是創(chuàng)建對象的簡化寫法,但是應(yīng)用場景非常有限讼稚。
- 匿名對象 :沒有變量名的對象括儒。
- 注意事項,匿名對象只能使用唯一的一次锐想,下次再用不得不再創(chuàng)建一個新對象帮寻。
- 使用建議:如果確定有一個對象只需要使用唯一的一 次,就可以用匿名對象赠摇。
格式:new 類名(參數(shù)列表);
舉例:new Scanner(System.in);
(二)應(yīng)用場景
1. 匿名對象直接調(diào)用方法
創(chuàng)建匿名對象直接調(diào)用方法固逗,沒有變量名浅蚪。
例:new Scanner(System.in).nextInt();
代碼:
public class Anoymous {
public static void main(String[] args) {
// 匿名對象
System.out.println(new Scanner(System.in).nextInt());
}
}
運(yùn)行結(jié)果:
一旦調(diào)用兩次方法,就是創(chuàng)建了兩個對象抒蚜,造成浪費(fèi)掘鄙。
new Scanner(System.in).nextInt();
new Scanner(System.in).nextInt();
2.作為方法的參數(shù)和返回值
(1) 作為參數(shù):
代碼:
public static void main(String[] args) {
// 普通方式
// Scanner sc = new Scanner(System.in);
// input(sc);
//匿名對象作為方法接收的參數(shù)
input(new Scanner(System.in));
}
public static void input(Scanner sc) {
System.out.println(sc.nextInt());
}
}
運(yùn)行結(jié)果:
輸入10:(2) 作為返回值:
代碼:
public class AnonymousTest2 {
public static void main(String[] args) {
Scanner sc = getScanner();
System.out.println(sc.nextInt());
}
public static Scanner getScanner() {
//普通方式
//Scanner sc = new Scanner(System.in);
//return sc;
//匿名對象作為方法返回值
return new Scanner(System.in);
}
}
運(yùn)行結(jié)果:
輸入10: