一、什麼是面向對象
1、面向過程思想
在理解面向對象思想之前,我首先來回顧一下以前c語言中的面向過程思想,面向過程思想強調的是過程(動作),在面向過程的開發中,其實就是面向着具體的每一個步驟和過程,把每一個步驟和過程完成,然而由這些功能方法相互調用,完成需求。面向過程的典型代表語言是:C語言。2、面向對象思想
①面向對象思想的由來
隨着需求的更改,功能的增多,發現需要面對每一個步驟太麻煩了,這時候就在思考,能不能把這些步驟和方法封裝起來,根據不同的功能,進行不同的封裝,用的時候,找到對應的類就可以了。這就是面向對象的思想。那麼,到底什麼是面向對象思想呢?
②面向對象思想概述
a、概念:面向對象是基於對象的編程思想。強調的是對象(實體),典型的語言是:C++,Java。
b、面向對象思想的特點:
- 是一種更符合我們思想習慣的思想
- 可以將複雜的事情簡單化
- 是我們從執行者變成了指揮者,角色發生了轉變。
- 首先,我們去尋找具備所需功能的對象來使用。
- 如果不存在這樣的對象,那麼我們就應該創建一個具備所需功能的對象。
- 這樣可以提高代碼的複用性,簡化開發。
a、買電腦:
- 面向過程:我得先了解電腦——瞭解我自己的需求——找對應的參數信息——去電腦城買電腦——討價還價——買回電腦。
- 面向對象:我知道我要買電腦——找一個瞭解電腦和會討價還價的人去買——別人幫我買回來了。
- 面向過程:把衣服脫下——找一個盆——放點洗衣服——加點水——把衣服扔進去——搓一搓——請洗衣服——晾乾——曬乾
- 面向對象:我要洗衣服——把衣服脫下來——找到洗衣機——丟進去,開啓洗衣機——洗完了,曬乾。
public class Demo1{
/*
把啤酒放進冰箱。
*/
public static void main(String[] args){
/*
面向過程:1、打開冰箱門。
2、把啤酒放進去。
3、關冰箱門
*/
//面向過程,調用方法:
open();
in();
close();
/*
面向對象:
如何思考才能更符合面向對象呢?
1、有那些類?
2、每個類有什麼東西呢?
3、類與類之間有什麼關係呢?
把啤酒放進冰箱的面向分析(名詞提取法)
a、有幾個類?大象,冰箱,Demo類
b、每個類有哪些東西呢?
————啤酒:進去
————冰箱:開,關
————Demo:main方法
*/
//面向對象,創建對象,對象調用方法
Beer beer = new Beer();
IceBox box = new IceBox();
box.open();
beer.in();
box.close();
}
public static void open(){
System.out.println("面向過程:打開冰箱");
}
public static void in(){
System.out.println("面向過程:把啤酒放進冰箱。");
}
public static void close(){
System.out.println("面向過程:關冰箱");
}
}
class Beer{
public static void in(){
System.out.println("面向對象:把啤酒放進去");
}
}
class IceBox{
public static void open(){
System.out.println("面向對象:打開冰箱");
}
public static void close(){
System.out.println("面向對象:關上冰箱");
}
}
我們在面向對象的開發中,就是不斷的創建對象,使用對象,指揮對象做事情。面向對象的設計過程,其實就是管理和維護對象之間的關係。⑤面向對象的思維方法
- 首先確定誰來做,其次確定怎麼做。
- 首先考慮是整體,其次考慮是局部。
- 首先考慮是抽象,其次考慮是具體。
面向對象有三大特徵,分別是:封裝(encapsulation)、繼承(inheritance)、多態(polymorphism)。
二、類與對象
1、什麼是類?什麼是對象?
①類和對象的概念
類是一組相關的屬性和行爲的集合。是構造對象的模板或藍圖。是一個抽象的概念。
對象是該類事物的具體表現形式。是一個具體存在的個體。
②類和對象的關係
對事物的描述通常包括兩方面:一個是屬性,一個是行爲。只要明確該事物的屬性和行爲並定義在類中即可。對象其實就是該類事物實實在在存在的個體。
類和對象的關係可以理解成:類——對事物的描述。對象——該類事物的示例,在java中通過new創建來的。
類與對象的關係如圖所示(圖紙就是類,汽車就是對象):
③成員變量
定義類其實就是定義類的成員(成員變量和成員方法)
成員變量其實就是類中的屬性。成員方法就是類中的行爲。
成員變量和局部變量的區別:
- 成員變量定義在類中,整個類都可以訪問;局部變量定義在函數中,語句局部代碼快中,只在所屬的區域有效。
- 成員變量存在於堆內存的對象中;局部變量存在於棧內存的方法中。
- 成員變量隨着對象的創建而存在,隨着對象的小時而消失;局部變量隨着所屬區域的執行而存在,隨着所屬區域的結束而釋放。
- 成員變量都有默認的初始化值;局部變量沒有默認的初始化值,必須先定義,賦值,才能使用。
④類與對象的代碼示例:
/*
事物:
屬性 事物的信息描述
行爲 事物的功能
類:
成員變量 事物的屬性
成員方法 事物的行爲
定義一個類,其實就是定義該類的成員變量和成員方法。
案例:我們來完成一個學生類的定義。
學生事物:
屬性:姓名,年齡,地址...
行爲:學習,吃飯,睡覺...
把事物要轉換爲對應的類:
學生類:
成員變量:姓名,年齡,地址...
成員方法:學習,吃飯,睡覺...
成員變量:和以前變量的定義是一樣的格式,但是位置不同,在類中方法外。
成員方法:和以前的方法定義是一樣的格式,但是今天把static先去掉。
首先我們應該定義一個類,然後完成類的成員。
*/
//這是我的學生類
class Student {
//定義變量
//姓名
String name;
//年齡
int age;
//地址
String address;
//定義方法
//學習的方法
public void study() {
System.out.println("學生愛學習");
}
//吃飯的方法
public void eat() {
System.out.println("學習餓了,要吃飯");
}
//睡覺的方法
public void sleep() {
System.out.println("學習累了,要睡覺");
}
}
⑤匿名對象(簡述,在以後用到會詳細說明)a,概念:一個定義在另一個類內部的類。
b,當一個對象方法僅進行一次調用的時候,就可以簡化成匿名對象。
c,匿名對象可以作爲實際參數進行傳遞。
三、封裝
1、封裝的概念
封裝是指隱藏對象的屬性和細節,但對外提供公共的訪問方式。
2、封裝的好處
封裝的好處主要在於:隱藏實現細節,提供公共的訪問方式;將變化隔離;便於使用;提高代碼的複用性;提高安全性。
3、封裝的原則
封裝原則主要是以下兩點:
a、將不需要對外提供的內容都隱藏起來。
b、把屬性都隱藏,提供公共方法對其調用。
4、private關鍵字
①private:私有,是一個權限修飾符,用於修飾成員。被private修飾的成員只有在本類中才能訪問。私有僅僅是封裝的一種體現而已。
②private常見的應用:將成員變量私有化,對外提供set和get方法對其進行訪問,提高數據訪問的安全性。
封裝的代碼示例如下:
/*
封裝和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(20);
System.out.println(s.getName()+"---"+s.getAge());
}
}
四、構造函數
1、構造函數詳解
①什麼是構造函數:構造函數是一種特殊的方法。具有以下特點:
a,構造方法的方法名必須與類名相同。
b,構造方法沒有返回值類型,也不能定義爲void,在方法名面前不聲明方法類型。
c,構造方法的主要作用是完成對象的初始化動作,它能把定義對象時的參數傳遞給對象的域。
d,一個類可以定義多個構造方法,如果在定義類時沒有定義構造方法,則編譯系統會自動插入一個無參的默認構造器,這個構造器不執行任何代碼。
e,構造方法可以重載,以參數的個數,類型,順序。
②構造函數的作用:給對象進行初始化。
③構造函數和一般函數的區別:
- 構造函數:對象創建時,就會調用與之對應的構造函數,對對象進行初始化;
- 構造函數,在對象創建時,會調用且只調用一次。
④什麼時候定義構造函數:在描述事物時,該事物已存在就具備的一些內容,這些內容都定義在構造函數中。
⑤構造代碼塊
a,作用:給對象進行初始化,對象一建立就運行,而且優於構造函數運行。
b,和構造函數的區別:
- 構造代碼塊是給對象進行初始化,構造函數是給指定的對象進行初始化。構造代碼塊中定義的是不同對象的共性內容。
/*
構造方法代碼演示
*/
class Student {
private String name;
private int age;
public Student() {
//System.out.println("我給了,你還給不");
System.out.println("這是無參構造方法");
}
//構造方法的重載格式
public Student(String name) {
System.out.println("這是帶一個String類型的構造方法");
this.name = name;
}
public Student(int age) {
System.out.println("這是帶一個int類型的構造方法");
this.age = age;
}
public Student(String name,int age) {
System.out.println("這是一個帶多個參數的構造方法");
this.name = name;
this.age = age;
}
public void show() {
System.out.println(name+"---"+age);
}
}
class ConstructDemo {
public static void main(String[] args) {
//創建對象
Student s = new Student();
s.show();
System.out.println("-------------");
//創建對象2
Student s2 = new Student("林青霞");
s2.show();
System.out.println("-------------");
//創建對象3
Student s3 = new Student(27);
s3.show();
System.out.println("-------------");
//創建對象4
Student s4 = new Student("林青霞",27);
s4.show();
}
}
2、類的初始化過程
Student s = new Student();在內存中究竟做了哪些事情呢?①加載student.class文件進內存。
②爲棧內存s開闢空間。
③爲堆內存學生對象開闢空間。
④對學生對象的成員變量進行默認初始化。
⑤對學生對象的成員變量進行顯示初始化。
⑥通過構造方法對學生對象的成員變量進行賦值。
⑦學生對象初始化完畢,將對象地址賦值給s變量。
3、this關鍵字
①this關鍵字的含義:代表對象,this就是所在函數的所屬對象的引用。簡單的說,哪個對象調用了this所在的函數,this就代表哪個對象。
②this關鍵字的應用
a、當成員變量和局部變量重名,可以用關鍵字this來區分。
b、this也可以用於在構造函數中調用其它構造函數。
注意:this只能定義在構造函數的第一行,因爲初始化動作必須要先執行。
如下代碼所示:
/*
this的實例。
this:哪個對象調用那個方法,this就代表那個對象
*/
class Student {
private String name;
private int age;
public String getName() {
return name; //這裏其實是隱含了this
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class StudentTest2 {
public static void main(String[] args) {
//創建一個對象
Student s1 = new Student();
s1.setName("歐陽");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
//創建第二個對象
Student s2 = new Student();
s2.setName("黃祥");
s2.setAge(30);
System.out.println(s2.getName()+"---"+s2.getAge());
}
}
五、Static關鍵字
1、static的特點
①static是一個修飾符,用於修飾成員。
②static修飾的成員被所有的對象所共享。
③static優先於對象而存在,因爲static的成員隨着類的加載就已經存在了。
④static修飾的成員多了一種調用方式,就是可以直接被類名所調用,類名.靜態成員。
⑤static修飾的數據是共享數據,對象中存在的是特有數據。
2、static關鍵字注意事項
①在靜態方法中不能使用this或者super關鍵字。
②靜態方法只能訪問靜態的成員變量和成員方法。(非靜態既可以訪問靜態也能訪問非靜態)
③主函數是靜態的。
3、成員變量和靜態變量的區別
①兩個變量的生命週期不同
- 成員變量隨着對象的創建而存在,隨着對象的回收而釋放。
- 靜態變量隨着類的加載而存在,隨着類的消失而消失。
- 成員變量只能被對象調用。
- 靜態變量可以被對象調用,還能被類名調用。
④成員變量數據存儲在堆內存的對象中,所以也叫對象的特有數據;靜態變量數據存儲在方法區(共享數據),所以也叫對象的共享數據。
4、主函數main解析
①主函數的特殊之處:格式是固定的;被JVM所識別和調用。主函數:public static void main (String[] args)
- public :因爲權限必須是最大的。
- static:不需要對象的,直接用主函數所屬類名調用即可。
- void:主函數沒有具體的返回值。
- main:函數名,不是關鍵字,只是一個被JVN所識別的固定的名字。
- String[] args:這是主函數的參數列表,是一個數組類型的參數,而且元素都是字符串類型。
5、靜態何時使用?
①靜態變量a、當分析對象中所具備的成員變量的值都是固定的,這時這個成員就可以使用靜態修飾。
b、只要數據在對象中都是不同的,就是對象的特有數據,必須存儲在對象中,是非靜態的。
c、如果是相同的數據,對象不需要做修改,只需要使用即可,不需要存儲在對象中,定義成靜態的。
②靜態方法
a、函數是否用靜態修飾,就參考一點,就是該函數的功能是否有訪問到對象中特有數據。
b、簡單的說,從源代碼看,該功能是狗需要訪問到非靜態的成員變量,如果需要,該功能就是非靜態的;如果不需要,該功能就可以定義成靜態的。
c、但是,非靜態需要被對象調用,而僅創建對象調用非靜態的,沒有訪問特有數據的方法,該對象的創建是沒有意義的。
靜態方法代碼示例:
/*
靜態方法
*/
class Teacher {
public int num = 10;
public static int num2 = 20;
public void show() {
System.out.println(num); //隱含的告訴你訪問的是成員變量
System.out.println(this.num); //明確的告訴你訪問的是成員變量
System.out.println(num2);
//function();
//function2();
}
public static void method() {
//無法從靜態上下文中引用非靜態 變量 num
//System.out.println(num);
System.out.println(num2);
//無法從靜態上下文中引用非靜態 方法 function()
//function();
function2();
}
public void function() {
}
public static void function2() {
}
}
class TeacherDemo {
public static void main(String[] args) {
//創建對象
Teacher t = new Teacher();
t.show();
System.out.println("------------");
t.method();
}
}
靜態變量代碼示例:/*
靜態變量示例
*/
class Student {
//非靜態變量
int num = 10;
//靜態變量
static int num2 = 20;
}
class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.num);
System.out.println(Student.num2);//靜態可通過類名調用。
System.out.println(s.num2);//靜態變量也可以通過類名調用。
}
}