1、類和對象
是構造對象的藍圖或模闆,我們可以将類想象成制作小甜餅的切割機,将對象想象成小甜餅,切割機是改變不了的,而制作出的小甜餅可以不同。由類構造對象的過程稱為建立類的執行個體。(一個抽象一個具體,可以自己多想一些這樣的例子友善了解)
-
類之間,最常見的關系有:(了解)
依賴(use-a):一個類的方法操縱另一個類的對象。(應該減少互相依賴的類。如果類A不知道B的存在,它就不會關心B的任何改變,就是讓類之間的耦合度最小)
聚合(has-a):類A的對象包含B的對象。
繼承(is-a):定義一個通用的類(父類),擴充該類為一個更加特定的類(子類)
- 一個類的組成
類名 class {
成員變量;
構造器;
成員方法()
public static void main(){
類名 p = new 類名();
//p叫執行個體,而不能說p是對象。執行個體在棧中,對象在堆中,操作執行個體實際上是通過執行個體的引用間接操作對象。多個執行個體可以指向同一個對象。厘清執行個體和對象。
}
}
- 成員變量:執行個體化對象後,對象通過類中的成員變量執行個體化形成自己的屬性(執行個體域,可能包含類中所有的成員變量,也可能是部分,這取決于構造器),通過對象的引用通路,對于成員變量在初始化之前都會有一個預設的初始值,這裡尤其要注意引用類型和内置類型初始值的不同。
- 構造器:伴随着new操作符的執行被調用地方法,一個對象必須經過這個步驟才能生成,但是對象地引用在對象造好之前就已經産生,故而有了this
public 類名(){}
A:用于将預設域初始化希望的狀态 (對于每個特定的類執行個體化對象後都有一組特定 的執行個體值域,這些值的集合就是這個對象的目前狀态)。
B: 支援重載(往往要通過一個類構造多個對象,不同對象的執行個體域可能不同)。
C: 不能對一個已經存在地對象調用構造器來達到重新設定執行個體域地目的。
-
成員方法:操作資料的過程,用于描述一個對象的行為,所有執行個體化後的對象都可以共享他。
這裡要注意:建立出來的對象隻包含屬于各自的成員變量,且并不包括成員方法。因為同一個類的對象擁有各自的成員變量,存儲在各自的堆中,但是他們共享該類的方法,并不是每建立一個對象就把成員方法複制一次。
- main()方法,是一個靜态方法,不對任何對象進行操作,事實上在啟動程式時還沒有任何對象,main()方法将執行并建立程式所需要的對象。
- 執行個體化一個對象具體幹了什麼?通過一個具體的類來說明
class Person{
private String name;
int age;
static String dynasty;
public Person(){
}
public Person(String name,int age){
this.name= name;
this.age = age;
}
public Person(String name,int age,String dynasty){
this.name = name;
this.age = age;
this.dynasty = dynasty;
}
public void show(){
System.out.println("name"+name+"age"+age+"dynasty"+dynasty);
}
public String getName(){
return name;
}
//public void setName(Person p1,String name){
//p1.name = name;
//}
public void setName(String name){//name是私有,是以給了構造來通路
this.name = name;
}
public void getAge(){
return age;
}
public void getAge(int age){
this.age = age;
}
}
public class PersonDemo{
public static void main(String[] args){
Person p1 = new Person("王陽明",3,"明");
p1.show();
Person p2 = new Person("徐階",15);
p2.show();
Person p3 = new Person("白居易",18);
p3.show();
p3.dynasty="唐";
p1.show();
//System.out.println(p1.getAge());
p1.setAge(999);
System.out.println(p1.getAge());
//p1.setName("張居正");
//System.out.println(p1.getName());
//p1.setName(p1,"王保保");
//System.out.println(p1.getName());
}
}
1、建立對象初始化的過程:
A:把Person.class加載到記憶體
B:在棧記憶體給變量p1開辟一塊記憶體空間
C:在堆記憶體為p1對象申請一個空間
D:給成員變量進行預設初始化,null,0,null
E:通過構造方法給成員變量執行個體化形成對象的執行個體域:王陽明,3,明
F:資料初始化完畢,然後把堆記憶體的位址值指派給棧記憶體的p1變量。

2、方法的調用
3、修改引用類型的值(this關鍵字的使用)
關于this關鍵字:目前對象的引用,因為在建立對象的時候第一步就是配置設定記憶體,已經有一個引用之後此時進入了構造之後是已經有了。用法
A:在構造方法中調用其他構造方法。調用語句必須出現在第一行,
B:通過this通路屬性或者方法(一般出現在命名遮擋的時候,name shadow)
public void setName(String name){
name = name;
}
在參數傳遞過程中,形參是引用類型,在堆中開辟記憶體儲存數值,然後引用給棧中的變量儲存,方法内的變量name總是遵循就近原則,這裡并不會比對到成員位置,而認為是形參的變量名,是以成了自己賦給自己了。
解決辦法:一種是差別形參的名字,防止遮擋,另外一種是借用this關鍵字引用,表明是目前引用通路的是對象執行個體域。
4、關于關鍵字static(static的含義就是和對象解綁)
從記憶體圖中可以看出靜态修飾的東西在方法區的靜态部分,屬于類,可以直接通過類名進行調用,但是執行個體化對象後在堆區仍然有靜态的标記,是以依然可以通過對象調用。靜态方法和屬性都不依賴于對象,是以也就無法使用this關鍵字。
小結注意:
- 類的成員變量被執行個體化的那些成員變量是對象的執行個體域,且存儲在堆上各自的對象中。并且類的成員方法是所有對象所共享的,隻有一份。
- 隻有在有對象需要調用方法時候,這些方法才會被壓入棧中,并且執行完畢後就自動釋放。
- 涉及到原理性的、記憶體類的東西往往比較博大精深,這隻是我的一 點小了解,如果有不當之處,再回來補漏洞吧。