類和對象
1、什麼是類
類相當于C語言中的一個高配結構體,類中既包含了資料又包含了動作(方法)
類存在的意義就是客觀事物進行一個抽象表示,與結構體相比,類的抽象能力更強(因為類中可以包含方法)
2.、類的執行個體化
用類類型建立對象的過程,稱為類的執行個體化;
在開發的時候:找對象 建對象 用對象 并維護對象之間的關系 這三點很重要
類就是一類執行個體的統稱,對象就是這一類具體化的一個執行個體
要想使用這個類(類是自定制類型),還需要把這個類型的變量給建立出來,這個變量就稱為
“對象(object)/執行個體(instance)”
基本文法:
class<class-name>{
field;//成員屬性
mothed;//成員方法
}
//執行個體化對象
<calss-name> <對象名稱>=new <calss-name>();
class 為定義類的關鍵字,class-name 為類的關鍵字 { } 中為類的主體。
代碼示例:
calss Person{
public int age;//成員屬性
public String name;
public String sex;
public void eat(){//成員方法
System.out.println("吃飯!");
}
public void sleep(){
System.out.println("睡覺!");
}
}
要注意:此處方法不帶static關鍵字;後面細說
3、同一個類可以建立多個執行個體
類隻是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有配置設定實際的記憶體空間來存儲它。
同一個類可以執行個體化出很多對象,執行個體化出的對象,就占用具體的記憶體空間,存儲類的成員變量。
類可以想象成圖紙,模型,對象就是根據這個圖紙,模型蓋出的房子
(java程式中,一般推薦一個 .java檔案中就隻放一個類。但是也不絕對)
calss Person{
public int age;//成員屬性
public String name;
public String sex;
public void eat(){//成員方法
System.out.println("吃飯!");
}
public void sleep(){
System.out.println("睡覺!");
}
public static void main(String [] args){
Person.person=new Person();//通過new執行個體化對象
//new關鍵字用于建立一個對象的執行個體
person.eat();//成員方法的調用需要通過對象的引用調用
person.sleep();
person.age=18;
//對象可使用‘.’來通路類中的屬性和方法
//産生對象,執行個體化對象
Person.person2=new Person();
Person.person3=new Person();
}
}
//執行結果:
吃飯
睡覺
建立出對象之後,就可以給這個對象中的屬性設定一定的值。
同時也可以去調用對象的方法。
設定值的時候也可以通過“.”來設定。
通過“.”就可以來調用對象中的方法。
并且方法内部是可以通路和使用到對象的屬性的
4、類的成員
包含:字段/屬性(field)、方法、代碼塊、内部類、接口等等;
4.1字段/屬性(field)
在類中,方法之外定義的變量。
用于描述一個類中包含哪些資料。
calss Person{
public int age;//成員屬性
public String name;
}
class Test{
public static void main(String [] args){
Person person=new person;
System.out.println(person.name);
System.out.println(person.age);
}
}
//執行結果
null
0
注意事項:
使用‘.’通路對象的字段
“通路”既包含讀,也包含寫
對于一個字段如果沒有設定初始值,那麼會有一個預設的初始值
預設值規則:
對于各種數字類型, 預設值為 0.
對于 boolean 類型, 預設值為 false.
對于引用類型(String, Array, 以及自定制類), 預設值為 null.
補充:java中的類型分成兩個大類
1.基本類型 int long short byte char boolean float double
2.引用類型 數組 String 自定義的類
java類中的屬性如果沒有初始化,也會有一個預設值(不是像C語言中整一個随機值)
其中如果是引用類型 初始的預設值就是null
如果是内置類型 初始預設值是0
如果是boolean類型 初始預設值是false
認識 null
null 在 Java 中為 “空引用”, 表示一個無效的對象. 類似于 C 語言中的空指針. 如果對 null 進行 . 操作就會引發異常.
class Person {
public String name;
public int age;
}
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name.length()); // 擷取字元串長度
}
}
// 執行結果
Exception in thread "main"java.lang.NullPointerException
at Test.main(Test.java:9)
字段就地初始化(直接定義變量的時候就初始化指派)
很多時候我們不希望字段使用預設值, 而是需要我們顯式設定初值. 可以這樣寫:
class Person {
public String name = "張三";
public int age = 18;
}
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
System.out.println(person.age);
}
}
// 執行結果
張三
18
4.2方法(method)
就是我們曾經講過的方法.
用于描述一個對象的行為.
class Person {
public int age = 18;
public String name = "張三";
public void show() {
System.out.println("我叫" + name + ", 今年" + age + "歲");
}
}
class Test {
public static void main(String[] args) {
Person person = new Person();
person.show();
}
}
// 執行結果
我叫張三, 今年18歲
此處的 show 方法, 表示 Person 這個對象具有一個 “展示自我” 的行為.
這樣的 show 方法是和 person 執行個體相關聯的. 如果建立了其他執行個體, 那麼 show 的行為就會發生變化
Person person2 = new Person();
person2.name = "李四";
person2.age = 20;
person2.show()
// 執行結果
我叫李四, 今年20歲
構造方法
類中存在一個特殊的方法,構造方法
在執行個體化對象的時候會被自動調用到的方法, 方法名字和類名相同, 用于對象的初始化.
雖然我們前面已經能将屬性就地初始化, 但是有些時候可能需要進行一些更複雜的初始化邏輯, 那麼就可以使用構造方法.
1.構造方法的名字和類名完全相同
2.構造方法沒有傳回值
3.構造方法new對象的同時被自動調用
構造方法是可以傳參數的
IDEA自動生成構造方法快捷鍵
alt +insert 鍵
4.3static關鍵字
static關鍵字
可以修飾:成員變量 /屬性 、方法、代碼塊、類
a.修飾一個成員變量/屬性
和對象無關,和類相關 不論這個類存在多少個對象,靜态成員變量隻存在一份
可以通過任何一個對象通路到這個成員變量 就算不建立對象,也可以用 類名. 的方式進行通路操作
通過static修飾的變量 跟對象無關 對象隻是能夠通路 跟類相關 也可以叫做類屬性
Java靜态屬性和類相關, 和具體的執行個體無關. 換句話說, 同一個類的不同執行個體共用同一個靜态屬性.
class TestDemo{
public int a;
public static int count;
}
public class Main{
public static void main(String[] args) {
TestDemo t1 = new TestDemo();
t1.a++;
TestDemo.count++;
System.out.println(t1.a);
System.out.println(TestDemo.count);
System.out.println("============");
TestDemo t2 = new TestDemo();
t2.a++;
TestDemo.count++;
System.out.println(t2.a);
System.out.println(TestDemo.count);
}
}
執行結果:
1
1
===========
1
2
記憶體分析:
count 被static修飾,所有類共享,且不屬于對象,通路方式為:類名.屬性
b.修飾一個方法 (讓方法脫離對象 和類相關)
如果在任何方法上應用 static 關鍵字,此方法稱為靜态方法。
靜态方法屬于類,而不屬于類的對象。
可以直接調用靜态方法,而無需建立類的執行個體。
靜态方法可以通路靜态資料成員,并可以更改靜态資料成員的值.
class TestDemo{
public int a;
public static int count;
public static void change() {
count = 100;
//a = 10; error 不可以通路非靜态資料成員
}
}
public class Main{
public static void main(String[] args) {
TestDemo.change();
//無需建立執行個體對象 就可以調用
System.out.println(TestDemo.count);
}
}
執行結果:
100
**注意:**修飾之後這個方法和類相關 和對象不相關。是以導緻了兩種情況
靜态方法不能直接使用非靜态資料成員或調用非靜态方法(非靜态資料成員和方法都是和執行個體相關的).
this和super兩個關鍵字不能在靜态上下文中使用(this 是目前執行個體的引用, super是目前執行個體父類執行個體的引用, 也 是和目前執行個體相關)
因為this這個關鍵字表示的是目前對象 是以在static修飾過後的方法(靜态方法)中不能使用this
我們曾經寫的方法為了簡單, 都統一加上了 static.
但實際上一個方法具體要不要帶 static, 都需要是情形而定. main 方法為 static 方法
//例如 xiaoli.eat(),而不能使用Person.eat();
public static void func(){
System.out.println(this.name+"這是一個靜态方法");
}
4.3.修飾代碼塊(這裡簡單介紹 後面詳細去說)
代碼塊功能和構造方法很類似,也可以用來初始化
相比之下構造方法可以傳參數,并且支援重載(可以有多個版本)
代碼塊中隻能去做一些固定的初始化
new對象的時候,先執行代碼塊中的内容,在執行構造方法,這個順序和代碼塊的書寫順序無關
static修飾代碼塊的時候 隻能初始化靜态成員
比如//public static int num=10;可以初始化num;
但是不能初始化和對象有關的變量
比如 name age sex
靜态成員num(public static int num=10;)num在靜态方法和普通方法中都能通路
在靜态代碼塊和普通代碼塊中也都能通路
但是對于普通成員(name age sex)在普通方法中能通路 在靜态方法中不能通路
在靜态代碼塊中不能通路 ,在普通代碼塊中不能通路
執行特點
兩個特點:
1:在執行過程中靜态代碼塊會最先執行
2:不管new多少個對象 靜态代碼塊隻執行一次
3:就算不建立新的對象也可以去使用靜态的代碼塊
4.4修飾類
後面細說
小結:
觀察下面的代碼:分析記憶體布局
class Person{
public int age; //執行個體變量 存放在對象内
public String name; //執行個體變量
public String sex; //執行個體變量
public static int count;//類變量也叫靜态變量,編譯時已經産生,屬于類本身,且隻有一份。存放在方法區
public final int SIZE = 10;//被final修飾的叫常量,也屬于對象。 被final修飾,後續不可更改
public static final int COUNT= 99;//靜态的常量,屬于類本身,隻有一份 被final修飾,後續不可更改
//執行個體成員函數
public void eat(){
int a = 10;//局部變量
System.out.println("eat()!");
}
//執行個體成員函數
public void sleep(){
System.out.println("sleep()!");
}
//靜态成員函數
public static void staticTest(){
//不能通路非靜态成員
// sex = "man"; error,sex是非靜态成員
System.out.println("StaticTest()!");
}
}
public class Test {
public static void main(String[] args) {
//産生對象 執行個體化對象
Person person = new Person();//person為對象的引用
System.out.println(person.age);//預設值為0
System.out.println(person.name);//預設值為null
// System.out.println(person.count);//會有警告!
//正确通路方式
System.out.println(Person.count);
System.out.println(Person.COUNT);
Person.staticTest();
//總結 :所有被static修飾對的方法或者屬性,全部不依賴于對象。
person.eat();
person.sleep();
}
}
//輸出結果:
0
null
0
99
StaticTest()!
eat()!
sleep()!
記憶體
JVM記憶體分成若幹個區域
1、JVM棧 局部變量 對象的引用
2、堆 就是用來存放new出來的對象 new Person(例如小花 小麗)
3、方法區 Person類(裡面有靜态變量)是以靜态變量儲存在方法之中