前言:
- 引出類與物件(oop) -- 為什么需要類與物件(oop)
- 例:我有兩只小狗,有姓名,年齡,性別,怎么完成該操作?
//用變數 String DogName = "小白"; int DogAge = 6; char DogSex= '公' String DogName = "小新"; int DogAge = 6; char DogSex= '公' //用陣列 String[] Dog = {"小白","6","公"}; //數字型別不明確 String[] Dog = {"小新","6","公"}; //數字型別不明確
- 上面案例中完成了小狗的屬性創建,那么現在我想給小狗添加一個愛好怎么辦?是不是特別麻煩,如果是100只小狗呢?
類與物件是什么:
- 看前言已經知道,用變數和陣列創建一個貓是多么的麻煩,增加一個屬性就需要重復大量代碼
- 類:如貓類 -> 把所有貓的屬性和行為提取到該貓類中形成一個類
- 貓類:是自定義的資料型別,如int就是java提供的資料型別
- 物件:如貓類 -> 提供貓類去創建出來的就是物件,貓物件

快速入門:
- 看下面代碼就可知道和原本的變數和陣列好處在哪,屬性型別明確,添加屬性值方便,開發效率高
public static void main(String[] args) { Cat cat1 = new Cat();//創建第一個貓物件 cat1.name = "小白";//給屬性賦值 cat1.age = 10; System.out.println(cat1.name +" "+ cat1.age);//輸出屬性值 Cat cat2 = new Cat();//創建第二個貓物件 cat2.name = "小新";//給屬性賦值 cat2.age = 20; System.out.println(cat2.name +" "+ cat2.age); } } class Cat{//定義一個貓類 String name;//屬性 int age; }
-
類屬性的不同叫法和細節:
Class Cat{ String name; // 可以叫 1.屬性 2.成員變數 3.欄位 int[] age; // 可以放所有基本資料型別和參考型別 doeble money; } pring(car.name+" "+car.age...)//直接輸出屬性,會輸出屬性默認值 //int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000, //boolean false,String null
-
物件記憶體布圖:

類和物件的記憶體分配機制:
-
java記憶體結構分析:
- 堆疊:一般存放基本資料型別(區域變數)
- 堆:一般存放物件或陣列
- 方法區:一般存放常量池和類加載資訊
-
java創建物件流程簡單分析:
- 創建物件然后在方法區加載類資訊 -- (只是加載一次,不會創建一個物件加載一次)
- 在堆中創建空間,進行默認初始化
- 把堆疊地址指向物件
- 進行初始化如:cat,pag = 10; cat.name = "小白"

成員方法:
- 什么是成員方法?就是在類在寫一個方法(方法是基礎里的知識),和寫一個屬性是一樣的
- 為什么需要成員方法?:
- 回圈遍歷一個陣列 是否需要寫代碼遍歷回圈,
- 在遍歷一個陣列呢,復制粘貼代碼在回圈一次?那我要改動遍歷代碼,所有的復制粘貼代碼都要改?
- 解決問題:所以只需要通過呼叫成員方法,就可以減少代碼的復用
-
快速入門:
public static void main(String[] args) { Cat cat = new Cat(); cat.show();//呼叫方法 } } class Cat{ String name = "小白"; /* public 公共的 -- 作用域(當然還有其它的) void -- 表示方法沒有回傳值 int -- 表示方法回傳值,基本資料型別,參考型別都可以 return -- 表示把值回傳 show-- 方法名 () -- 形參串列,表示可以接收形參 {} -- 方法體 */ public void show(){ //方法體 System.out.println("我叫"+name); }
//有參回傳 public int show2(int i, int n ){ return i+n; } }
-
方法呼叫機制:

-
方法的定義:
訪問修飾符 回傳資料型別 方法名(形參串列..) {//方法體
陳述句;
return 回傳值; //如果是viod就需要該存在了
}
-
成員方法的下細節:
- 一個方法最多一個回傳值(但是可以有多個回傳結果,回傳陣列形式)
- 可以回傳任意型別,基本資料類參考型別(陣列,物件)
- 如果方法是void,不需要寫return,或者只寫return(不能用回傳值)
- 回傳值型別return必須和回傳值統一或者兼容,如:需要回傳值是double,return可以回傳int,反過來就不可以需要資料型別可以轉換
- 遵循駝峰命名法
class Dog{ //1.回傳多個結果 public int[] king(){ int[] sum = new int[3]; sum[0] = 1; sum[1] = 2; return sum; //回傳多個結果 } //2.void可以寫return,但不能有回傳值 public void king2(){ pring("加油"); return; } //3.可以回傳兼容的型別 public double king3(){ int i = 99; return i ; } }
-
成員方法 - 形參串列細節:
- 一個方法可以有0個引數,也可以有多個引數有逗號隔開
- 引數型別可以是任意型別,基本資料型別或參考型別
- 呼叫引數方法時,傳入的引數一定是相同的型別或兼容的型別
- 方法定義時的引數叫形參(形式引數),呼叫方法時傳入的叫實參,實參和形參必須統一或兼容
//一個方法可以有0個引數,也可以有多個引數有逗號隔開 public int show(int num1, int num2){ return num1+num2; } //引數型別可以是任意型別,基本資料型別或參考型別 public int[][] show2(int[][] map){ int[][] nums = new int[11][11]; return nums; }
-
成員方法 - 方法體細節:
- 方法體中不能嵌套方法
-
成員方法 - 方法呼叫細節:
- 同類中可以直接呼叫同類中的其它方法
- 在方法中可以通過物件呼叫其它類中的方法 - 這里注意因為跨類呼叫還需要考慮訪問修飾符
class A{ public void print(){ System.out.println("我在同類中的其它方法呼叫了"); } //同類中可以直接呼叫其它方法 public void sayOK(){ print(); System.out.println("我呼叫了print()方法"); } //在方法中可以,通過物件呼叫其它類方法 public void m1(){ System.out.println("A的m1被呼叫"); new B().hi(); System.out.println("A的m1現在執行 "); } } class B{ public void hi(){ System.out.println("我是B類的hi()方法"); } }
-
成員方法 - 基本資料型別傳遞機制
- 基本資料型別傳遞的是值拷貝,形成不會改變實參

-
成員方法 - 參考型別傳遞機制
- 參考型別傳遞的是地址 - 會對參考型別改變
- 如果在方法中改變了傳遞過去的地址,改變了地址或指空,那么對參考型別不會進行影響

方法的多載:
- 什么是多載?-> 同一個類中,多個方法名稱一樣的方法存在,但是形成串列不一致
- 多載的好處 -> 如我的方法是顯示加法后的結果,那可以是int加int,doblue加int,那么可以通過同一方法名來實作,只需要傳遞不同的引數
class AA{ public void show(int i ,int n){ System.out.println(i+n); } public void show(int i ,double n){ System.out.println(i+n); } public void show(double i ,double n){ System.out.println(i+n); } public void show(double i, int n){ System.out.println(i+n); } }
-
多載細節:
- 方法名必須相同
- 形成串列不能一致
- 可以是任意回傳型別(如:可以回傳int double void Cat 陣列型別 等)
//回傳形成串列不能一致,回傳型別不同也不行 public void show(double i ,double n){ System.out.println(i+n); } public double show(double i ,double n){ System.out.println(i+n); }
可變引數:
- 什么是可變引數?就是可以傳遞零個或多個數
- 使用可變引數,可以當陣列使用
- 語法:int... sum -- 就是int型別的可變引數
public int sum(int... nums){ int res = 0; for (int i = 0; i < nums.length; i++) { res += nums[i]; } return res; }
-
可變引數 - 細節:
- 可變引數實參可以是0個或多個
- 可變引數的實參可以是陣列
- 可變引數本質就是陣列
- 可以引數可以和普通型別引數一起放在形成串列中,可變引數必須放在普通引數后面
- 一個形成串列,只能出現一個可變引數
public class Test { public static void main(String[] args) { AA aa = new AA(); //可變引數的實參可以是陣列 int[] num = {1,2,3}; int sum = aa.sum(num); } } class AA{ public int sum(int... nums){ int res = 0; for (int i = 0; i < nums.length; i++) { res += nums[i]; } return res; }
//可以引數可以和普通型別引數一起放在形成串列中,可變引數必須要在普通型別引數后面 public void sum(String name,int... nums){ };
//一個形成串列只能出現一個可變引數 //public void sum(double... num,int... nums){};//錯誤 }
作用域:
- 什么是作用域?就是屬性在該類中的使用范圍
- 作用域一般訪問:全域變數和區域變數
- 全域變數:在該類中都可以使用
- 區域變數:只能在自己的一畝三分地使用,在自己的代碼塊中使用
//快速入門 class AA{ //該屬性在AA類中都可以訪問 String name = "king"; //成員變數/屬性/全域變數 public void show(){ //成員方法 //該屬性只能在show()方法中使用 char sex = '男'; //區域變數 } }
-
作用域細節:
- 全域變數(屬性)有默認值;區域變數沒有默認值(定義時必須賦值)
- 全域變數(屬性)和區域變數名字可以重復,訪問時就近原則,靠我近訪問誰
- 全域變數(屬性)可以使用訪問修飾符,區域變數不可以
- 全域變數(屬性)伴隨著物件的銷毀而銷毀,區域變數是代碼塊的銷毀而銷毀
- 通俗易懂版:new一個物件,該物件不銷毀全域變數還在,區域變數一般中方法中,如方法結束區域變數就銷毀
class AA{ //1.屬性默認值:String是null String name; //2.屬性和區域變數名字可以一致,就近原則訪問 int age; //3.屬性可以使用訪問修飾符 public char sex; public void show(){ //1.區域變數:沒有默認值,不寫就錯 char sex = '男'; //2.屬性和區域變數名字可以一致,就近原則訪問 int age = 18; } }
構造器:
- 什么是構造器?完成對新物件的初始化
- 理解:呼叫構造器時,物件已存在記憶體中,呼叫構造器去完成物件屬性的的初始化
- 在理解:等于AA類中有 String name; 我的操作等于 String name = "小白";
- 語法:【修飾符】類名 (形參串列) {代碼塊}
class AA{ String name; int age; public AA(String name,int age){ System.out.println("name+age"); name = name; age = age; } }
-
構造器 - 細節:
- 可以構造器的多載
- 控制器沒有回傳值
- 控制器名和類名相同
- 構造器完成物件的初始化,不是創建物件
- 類中沒有定義構造器,系統默認是給一個默認的無參構造器
- 定義了自定義的構造器后,默認的構造器就會被覆寫,需要重新定義才能使用

物件創建的流程+構造器版本:
- 類加載
- 在堆在分配空間 == 空物件
- 物件初始化 - 屬性先賦值(默認值先賦值,在到定義值,在到構造器)
- 堆疊中接收堆中地址
this關鍵字:
- 什么是this?我直接呼叫我自己
- 為什么要使用this?如:構造器中形參為 name 類屬性 name 我要name = name怎么辦?是不是太含糊不清,誰是誰的name
- 案例說明什么是,我直接呼叫我自己:
public class Test { public static void main(String[] args) { AA aa = new AA("小白",20); //1.呼叫該方法name = null,age = 0 aa.show(); } } class AA{ String name; int age; public AA(String name, int age) { //2.因為:這里把name當成了區域變數 //自己 給 自己 賦值肯定是錯誤的 name = name; age = age; //3.this.name表示當前物件的name屬性 //當前物件是誰?AA aa = new AA("小白",20); //所以說是:我自己呼叫我自己 this.name = name; this.age = age; } public void show(){ System.out.println(name+" "+age); } }
-
深入了解,我自己呼叫我自己:
- 每個物件都會有一個hashcode,Java可以通過這個hashcode來識別一個物件
-
this細節:
- this關鍵字可以訪問,本類屬性,方法,構造器
- 訪問方法語法:this.方法名(引數串列)
- 訪問構造器語法:this(引數串列) - 必須寫在構造器中使用,必須在構造器中第一條中,不能遞回呼叫(就是我呼叫你,你呼叫我)
- this關鍵字可以區分屬性和區域變數
- this關鍵字只能在類定義的內部使用,去類外部使用誰知道this是什么
- this關鍵字可以訪問,本類屬性,方法,構造器
class AA{ String name; int age; public AA(String name, int age) { //this關鍵字訪問本類構造器 this("小白"); //this關鍵字訪問本類屬性 this.name = name; this.age = age; } public AA(String name) { String name = "oop"; //this關鍵字可以區分屬性和區域變數 this.name = name; this.age = age; } public void t1(){ //this關鍵字可以訪問本類方法 this.t2(); System.out.println("我是t1"); } public void t2(){ System.out.println("我是t2"); } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500369.html
標籤:其他
上一篇:SpringMVC實戰入門教程,四天帶你快速搞定springmvc框架
下一篇:Pandas簡單操作(學習總結)


