OOP
------
Oriented object program,面向對象編程。
OOA
------
Oriented object analyze,面向對象分析。
OOD
------
Oriented object design,面向對象設計
一切都是對象.
面向過程的.
----------
c:
entity:實體。
new 關鍵字,創建對象
理解面向對象
將功能封裝進對象,強調具備了功能的對象
不斷使用對象,創建對象,再使用對象
--------------------------------------
面向對象的特徵
1.封裝
2.繼承
3.多態
對象
--------
切實存在的個體。
類
------------
物以類聚,人以羣分。
人找人,蝦找蝦。
對現實事務的軟件抽象。
類成員
----------
1.成員變量(事物的屬性)
屬性
有默認初始化值:
數值類型的基本數據類型默認值是0
對象或引用類型的就是null空值
存放在堆區
定義在類中,在整個類中都可以訪問,不受順序影響
隨着對象的建議而建立,存在於對象所在的堆內存中。
2.成員函數(事物的行爲,能做什麼,)
方法.
如果是靜態的方法,不用創建對象就可以拿到;如果一定要通過創建對象拿到方法就需要佔用內存空間(不是必須就不要開闢內存空間造成浪費)
3.定義方式
class 類名{ 成員變量; 成員函數} //每個單詞首字符大寫,特殊字符只能以$_開頭。
4.對象的造創
局部變量
-----------
定義在方法或者語句中。
沒有默認的初始化值,如要訪問局部變量必須初始化,否則報異常;
存放在棧中。
所在範圍結束後,空間自動釋放。生存週期只在所在成對大括號內(方法內)
堆
----------
數組和對象在堆中。
棧
-----------
方法在棧中 先進後出 main方法首先壓入棧
壓入的是方法針,在一針內有局部變量,這個局部變量週期僅在這一針內有效。
push 壓棧(載入方法) pop 彈棧(彈出方法)
方法運行完成後,就彈出
堆區和棧區都是在程序運行時纔會生成
示例及說明:創建對象 和使用對象
-----------------------------------
/**
*定義一個類示例
*/
class ClassDemo1{
public static void main(String[] args){
//創建一個Person的對象,這裏共有三個過程:
//1.創建局部變量,
//2.開闢內存空間(在堆中創建對象),產生內存地址。
//3.將內存地賦值給第1步的局部主量中,局部變量只是引用內存地址。
Person p = new Person(); //p爲局部變量
//使用對象,給對象的屬性賦值
p.height = 180 ;
//調用對象的方法 .加方法名,如有參數在括號內輸入參數
p.run();
//使用屬性
System.out.println(p.height);
}
}
/**
*定義一個人的類
*/
class Person{
//成員變量:屬性(property):字段(field)
int height ; //身高
int weight ; //體重
int age ; //年齡
//定義一個成員函數:方法 run跑的方法,人是可以跑的
public void run(){
System.out.println("run...");
}
}
-------------------------------------------
堆棧溢出指的是棧溢出
-------------------------
StackOverflow:棧溢出
堆比棧大
--------------------------
//負值數組大小異常(NegativeArraySizeException),數組長度過長被截斷,首位符號位爲1,變成負數,導致數組大小異常
NegativeArraySizeException
Exception in thread "main" java.lang.NegativeArraySizeException
at StackHeapDemo.main(StackHeapDemo.java:4)
-----------------------------------------------------
//內存不足錯誤(OutOfMemoryError)
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exce
eds VM limit at StackHeapDemo.main(StackHeapDemo.java:4)
--------------------------------------------------------
double d ;
long
1byte
1024 = 1K
2^10 = 1024
1kb = 1024 byte
1mb = 1024k byte
1gb = 1024m byte = 1024 x 1024 x 1024 ;
1tb = 1024g byte
1pb = 1024t byte
1eb = 1024pb
1zb = 1024eb
1yb = 1024zb
1nb = 1024yb
jvm堆棧初探
------------------
在命令行下執行
1.jps [-v] //查看運行的java進程:
2.jmap -heap pid //查看指定java進程的堆空間
//jmap 也是jak自帶工具
//linux 下切換爲root
3.java中對象和數組位於堆內存中,局部變量、函數參數等位於棧內存中
4.棧默認空間大小是1m。
5.堆默認空間大小是1/4物理內存.
java VM調整堆大小
java -X //查看java非標準輸出幫助
java -Xmx100m //設置jvm的堆空間最大值
java -Xms100m //設置jvm的堆空間初始值
堆溢出
---------------------------
//堆溢出,使用整形最大值作爲數組長度,直接導致堆溢出
//byte[] arr0 = new byte[Integer.MAX_VLAUE];
JVM虛擬機調優,調堆的初始化和最大值的空間大小;這兩個值通常設置成一樣的大小。
例:
//內存不足錯誤(OutOfMemoryError)
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exce
eds VM limit at StackHeapDemo.main(StackHeapDemo.java:4)
=======================================================
棧溢出(StackOverflowError)
-------------------------------------
例://通過死循環調用方法,導致棧溢出演示,
//當需要調用過多的方法時,如果出現溢出可調整棧空間大小,但一般很少調整此項,演示中的死循環爲程序BUG。
class StackHeapDemo{
public static void main(String[] args){
out(1);
}
public static void out ( int i){
System.out.println(i);
out(i + 1);
}
}
//執行結果
11400
11401
11402
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.ext.DoubleByte$Encoder.encodeLoop(Unknown Source)
at java.nio.charset.CharsetEncoder.encode(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at StackHeapDemo.out(StackHeapDemo.java:15)
at StackHeapDemo.out(StackHeapDemo.java:16)
java VM調整棧大小(很少需要調整棧方法)
------------
java -Xss2m //設置Java線程堆棧大小
棧默認空間大小是1m。
匿名對象:
不創建變量,直接創建對象,不需要通過變量保持
-------使用形式---------
1.new Person().run(); //匿名對象可直接調用對象中的屬性和方法,只訪問一次。
2.run(new Person()); //作爲參數進行傳遞
封裝(Encapsulation)
-----------
將部分成員隱藏起來,外界只能通過其他方式進行方法。
使用private進行修飾,保證安全性。
好處:
1.將變化隔離;
2.便於使用;
3.提高重用性 ;
4.提高安全性
封裝原則:
1.將不需要對外提供的內容都隱藏起來
2.把屬性都隱藏,提供公共方法對其方問
private : 私有的
1.修飾符;
2.用於修飾成員變量和成員函數;
3.被私有化的成員只能在本類中有效;
4.常用之一:將成員變量私有化,對外提供set(修改)和get(獲取)方法對其訪問,提高數據訪問安全性。
public : 公有的
private 和public的常用方法
------------------------
一個類的中屬性一般都是私有的,防止非法訪問,然後通過公有的方法進行修改屬性,經過方法處理後,可以有效管理修改屬性的權限。
這種方法就是典形的一種封裝形式。
常用方法命名 (動詞加名稱,首字母小寫,後面單詞首字母大寫)
--------------------------------
獲取開頭單詞用 get 例:getMoney
修改開頭單詞用 set 例:setMoney
構造函數
--------
1.函數名和類型相同
2.不用定義返回值類型
3.沒有返回值.
創建之後肯定返回的是該類的對象,所以無需設置返值
4.如果類未定義構造函數,jvm將會分配一個空構造函數。
如果類定義了構造函數,jvm將不會分配空構造函數,必須自己定義空構造函數
5.作用:給對象進行初始化。
6.可以重載:函數名一樣, 參數不一樣
7.創建對象時,就需要指定構造函數,按參數類型判斷使用哪個構造函數
Car c1 = new Car(); \\無參創建
Car c2 = new Car("white"); \\傳參創建,參數可以有多個
構造代碼塊
----------
1.創建對象時調用.(可以有多個構造代碼塊,)
2.構造函數之前。
3.如果所有構造代碼塊有相同的代碼,可以將這部分代碼寫入構造代碼塊中。
4.
對象創建過程
-----------
0.靜態代碼塊
從上到下按序執行。
1.構造代碼塊
從上到下按序執行。
2.構造函數
3.成員變量
a.color = null ;
b.color = "black" ;
c.構造代碼塊
d.構造函數.
4.
類成員組成 及 相互關係
------
1、成員變量
2、成員函數
3、構造函數
4、構造代碼塊
5、局部代碼塊(包含在函數內部,僅函數內部有效)
6、靜態代碼塊:在類加載期間執行,而且只執行一次,通常是完成一些初始化工作,就是所有對象都有同樣的初始化過程,例如:連接數據庫
7、靜態成員之間可以互相訪問,按序執行。
8、靜態成員不可以訪問非靜態成員。
9、非靜態成員可以訪問靜態成員。
10、靜態成員通過類訪問(和對象無關 訪問方式:類名.靜態成員名)。
11、靜態方法中不可以用this super關鍵字
12、靜態方法只能訪問靜態成員;
JVM運行後,各區域加載順序 方法區、棧區、堆區
----------------------------------------------------------------------------
方法區:靜態成員
棧 區:方法 、 局部變量
堆 區:數組 、 對象
javabean
---------
在計算機專業術語中,很多單詞是專業用詞,是不需要翻譯的。
pojo :plain old java object 普通古老的JAVA對象
pojo指的就是最標準的java類,一般針對一些名稱,這些名詞用術語來講又叫實體類。
例
class Dog{
private String color ; //成員變量是私有的
public String getColor(){ //並有成員變量對應的 讀取get 、設置 set的 方法
return color ;
}
}
this.xxx
-------
指向對象自身的引用,類似成員變量,使用private修飾。
靜態方法不可以使用this。
this() this (構造函數的參數)
-------
訪問當前類的構造函數。(用於調用自己類中的)
this()的調用必須是第一條語句。
爲了構造函數的重用(在構造函數中引用其他構造函數時,在第一條語句,可以使用this引用其他構造函數)
super() 在構造函數中使用
-------
1.訪問超類的構造函數。(用於調用父類(超類)的空構造函數,如果沒有見第4條)
2.必須是第一行代碼。
3.構造函數的首行要麼是this(),要麼是super(),默認是super();
4.如果父類無空構造函數,子類的第一行super調用的就是父類的空構造,因爲沒有了空構造調不出來了,兩種解決方式:1給父類加空構造函數;2就需要在子類中的空構造函數中使用super()指定超類的構造函數 super(參數))
例:-------------------------------------------
//定義一個動物類
class Animal{
String color ;
int height ;
//這裏沒有Animal的空參的構造函數,只有一個帶參的構造函數
public Animal (String color ){
this.color = color ;
}
}
//狗類
class Dog extends Animal{
//因爲Animal父類的空構造函數已沒有了,需要使用super(參數) 指定一個父類的構造函數
//在當前類中創建一個空構造函數,用super(參數) 來指定父類的一個存在的構造函數;
public Dog(){ //創建一個子類的空構造函數
super("white"); //用super加參來指定父類的構造函數
}
}
class Jing8 extends Dog{
public Jing8(){
super();
}
String owner ;
}
-----------------------------------------------------------
5.每個空構造函數第一行都有一個super,只是省略掉了。
super() 與 super.xxx 是不同的
super.xxx
----------
1.訪問超類的成員。
例說明:
超類 A1 有 run() 方法
父類A2(A1的子類) 也有 run()方法
子類A3(A2的子類)調用run()方法 只調用父類的(如果想要同時調用到超類及父類的可以在父類A2中的run()方法中加上 super.run() 來調入超類A1中的run()方法)這樣A3在調用run()方法時,就會同時調用A1和A2中的run()方法.
2.當使用super.xxx調用方法時,指的是父類對象的一個引用,可以不用寫在第一行
super關鍵字簡要介紹
super和this的用法相像
this代表本類對象的引用
super代表父類的內存空間標識
當子父類出現同名成員時,可以用super進行區分
子類要調用父類構造函數時,可以使用super語句。
函數覆蓋 (成員變量是不可以被覆蓋的)
---------
(當父類的方法與子類的方法相同時,以子類方法的行爲爲準)
1.overwrite
重寫
複寫
2.只有在繼承的時候纔有重寫。
3.private方法不可以覆蓋。
繼承概述
1、多個類中存在相同屬性和行爲時,將這些內容抽出到單獨的類中,那麼多個類就不用再定義,只要繼承那個類即可
2、多個類稱爲子類,單獨這個類稱爲父類或超類
3、子類可以直接訪問父類非私有屬性和行爲
4、通過 extends 關鍵字讓類與類之間產生繼承關係
class SubDemo extends Demo{ }
5、繼承的出現提高了代碼的複用性,
6、讓類與類之間產生了關係,提供了多態的前提。
繼承
------
1.extends
2.類只支持單重繼承
3.支持多層繼承.
多態:
-------------------
可以簡單從字面理解,多種狀態,多種形態
成員函數
--------
成員變量 (相比成員函數重要)
--------
1.因爲變量是最基礎的數據,函數只是一個過程
2.最基礎的數據是最重要的,所以在繼承中是不能被覆蓋的。