1. 程式人生 > >Java基礎---面向物件(面向物件,類,物件,匿名物件,封裝,建構函式,構造程式碼塊,this,static,main,幫助文件,靜態程式碼塊,單例)

Java基礎---面向物件(面向物件,類,物件,匿名物件,封裝,建構函式,構造程式碼塊,this,static,main,幫助文件,靜態程式碼塊,單例)

一. 面向物件概念:

面向物件其實是一種思考的思想,早期思想是面向過程。
面向過程注重的是過程,過程所涉及的行為,也就是功能。

【例項】:面向過程: 1. 把冰箱開啟 2. 把大象放入 3. 冰箱關起來
     面向物件: 開啟冰箱,儲存,關閉都是對冰箱的操作,是冰箱的行為。冰箱就是一個物件,所以只要操作冰箱所具備的功能,都要定義在冰箱中。

冰箱儲存

【總結】: 所屬在冰箱中,先看到冰箱,有了冰箱就有了這些功能,把這些功能封裝在冰箱中。
      先找到這些功能有哪些特性,所屬於什麼事物,找到事物,把功能全封裝進去。

【面向物件概念】

  1. 面向物件是思考問題的一種思考方式,是一種思想。
  2. 面向物件的好處:將複雜的事情變簡單了,只要面對一個物件就行。

【面向物件設計】

面向物件設計把握一個重要的經驗:誰擁有資料,誰對外提供操作這些資料(私有)的方法!
(被動的一方是資料的擁有者,主動的一方是執行者)

【例項 1】:人在黑板上畫園:
     => 物件:person, blackboard, circle

draw() //畫圓
{
    (x, y)  //圓心
    radius  //半徑
}

/*圓心和半徑是circle內部的資料,畫圓的方法要操作圓心和半徑
  所以畫圓的方法是圓提供的。
*/



【例項 2】:列車司機緊急剎車
     => 物件:司機, 列車
     => 剎車的動作:列車身上的方法


【例項 3】:售票員統計收穫小票的金額
     => 物件:售票員, 小票
     => 統計收穫小票的金額的方法:是小票身上的方法。
      因為商品的價格是在小票內部的資料,售票員只是呼叫小票的getTotalMoney( )


【例項 4】:你把門關上了:[ 名稱提煉法 ]
     => 物件:門, 人
     => 關門的方法:是門身上的方法,人只是呼叫門的closeDoor( )

closeDoor() //關門
{
    //旋轉; 裝到門框; 伸出鎖舌; 插到鎖孔;
}



【例項 5】:路上有很多汽車,路上還隨時可以增加,減少汽車:
     => 物件:路, 汽車
     => 增加,減少汽車的方法:是路身上的方法,不是汽車自己衝過去的。


【例項 6】:球從一根繩子的一端移動到了另一端:
     => 物件:球, 繩子
     => 繩子:為球的移動指引了方向 nextPoint( )
      球:move( )

class Rope
{
    private Point start;
    private
Point end; public Rope(Point start, Point end) { this.start = start; this.end = end; } public Point nextPoint(Point currentPoint) { /*通過兩點一線的數學公式可以計算出當前點的下一個點 * 如果當前點是終點,則返回null; * 如果當前點不是線上的點,則拋異常。 * */ } } class Ball { private Rope rope; private Point currentPoint; public Ball(Rope rope, Point currentPoint) { this.rope = rope; this.currentPoint = currentPoint; } public void move() //設定為定時器,每隔1秒move一次 { currentPoint = rope.nextPoint(currentPoint); System.out.println("小球移動到了" + currentPoint); } }



【例項 7】:兩塊石頭磨成一把石刀,石刀可以砍樹,砍成木材,木材可以做成椅子:
     => 物件:stone  (自己變成石刀,自己都沒有了,所以不是自己的方法)
         stoneknife => stoneKnife = KnifeFactory . createKnife( Stone first, Stone second )
         tree
         material  => material = stoneKnife . cut( tree )
         chair    => chair = ChairFactory . createChair( material )

【面向物件的三個特徵】

面向物件的三個特徵:封裝,繼承,多型。

開發時:找物件,建物件,用物件,並維護物件之間的關係。

二. 類與物件的關係:

1. 類與物件的關係

  1. 類就是對現實生活中事物的描述。
  2. 物件就是這類事物,實實在在的個體。
【分析】:張三,李四 【對映到記憶體中】:
現實生活中的物件:張三,李四。

物件:在Java中用new操作符所產生的一個實體,這個實體在堆記憶體中。

一個實體(具體物件)
想要描述:提取物件中共性內容,對具體的抽象

描述時,這些物件的共性有:姓名,年齡,性別,學習Java的能力。
一個類(class定義的類)


【例項】:需要描述汽車,描述事物 其實就是描述事物的屬性行為

  1. 【描述事物】:定義類
  2. 【屬性和行為】:類中的成員(成員變數,成員函式)
  3. 【屬性】:類中的變數
  4. 【行為】:類中的函式

描述汽車

public class CarDemo {

    public static void main(String[] args) {
        //生產汽車,在Java中通過new操作符來完成,其實就是在堆記憶體中產生一個實體。‘

        Car c = new Car(); 
        //c 是引用型別變數,就是類型別變數,指向物件,即指向該類產生的實體。
    }

}

class Car
{
    String color = "red"; //描述顏色
    int num = 4; //描述輪胎數

    /**
     * 執行行為
     */
    public void run() 
    {
        System.out.println(color + "..." + num);
    }
}

2. 物件的記憶體分配

【例項 1】物件的記憶體分配情況一。

物件的記憶體分配1

【分析】:

  1. [ new Car( ) ]:新建一個實體。
  2. 堆記憶體中的變數都有一個特點:預設初始化值。
    如果c.color沒有顯示初始化值,它的預設初始化值為null(因為字串預設初始化值為null)。

【例項 2】物件的記憶體分配情況二。

物件的記憶體分配2

【分析】:

  1. [ Car c1 = c ] :叫多引用指向同一物件
  2. [ c1.run( ) ]:結果為 color = “green”;  num = 5;
【總結】:
1. 物件的特點:用於封裝資料(屬性,行為)

2. 類不獨立執行可以沒有主函式,在主函式中建立類的物件,可以呼叫該類中的屬性方法。

3. 【成員變數與區域性變數的區別】: (1)作用不一樣: 成員變數:作用於整個類
區域性變數:作用於函式中,或者語句中

(2)在記憶體中的位置: 成員變數:在堆記憶體中,因為物件存在才在記憶體中存在。
區域性變數:存在棧記憶體中


class Car
{
    String color = "red"; //描述顏色
    int num = 4; //描述輪胎數  【?】

    /**
     * 執行行為
     */
    public void run()
    {
        System.out.println(color + "..." + num); //成員變數作用在整個類中,可以直接訪問。
    }

    /**
     * 在本類中建立本類物件
     */
    public static void main(String[] args)
    {
        Car c = new Car();
        c.num = 10;  //這個變了,但是【?】處沒變,相當於car變了,圖紙沒變。
    }
}

3. 匿名物件

物件可以起名字,也可以不起名字。匿名物件是物件的簡寫形式。

【匿名物件的使用方式】:
【方式 1】 (1)當物件的方法只調用一次時,可以用匿名物件來完成,這樣寫比較簡化。

【例項】:

   Car c = new Car( );
   c.num = 5;

 => new Car( ).num = 5;

(2)如果對一個物件進行多個成員呼叫,必須給這個物件起名字。

【例項】:記憶體洩露
匿名物件的記憶體分配
【方式 2】 匿名物件可以作為實際引數進行傳遞。


【例項】:汽車修配廠,對汽車進行改裝,將來的汽車都改成黑色,三個輪胎。

1. [ 法一 ]:沒有采用匿名物件。
物件的記憶體分配

【分析】:show 執行結束完,物件c 還被main引用,當mian結束才變為垃圾。要提前變為垃圾:c = null;

2. [ 法二 ]:採用匿名物件。
匿名物件的記憶體分配

【分析】:

 (1)[ show( Car c){ } ]:相當於Car c = new Car( ); 堆記憶體中的new Car( )不是垃圾,被show中的c 引用。

 (2)當show執行結束後,show為垃圾,實際引數的匿名物件沒有引用,也變為垃圾。


三. 封裝:

封裝是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式。

【封裝體】: 函式就是最小的封裝體,類也是封裝體,包,框架(用於元件的開發)等。
【好處】: 將變數隔離,便於使用,提供重用性,提高安全性。
【原則】: 將不需要對外提供的內容都隱藏起來,把屬性都隱藏,提供公共方法對其訪問。
【private】: 私有,許可權修飾符:用於修飾類中的成員(成員變數, 成員函式),私有隻有在本類中有效。


【例項 1】:將年齡私有化

public class Demo {

    public static void main(String[] args) {
        Person p = new Person();
//      p.age = -20;  //訪問不到
        p.speak();

    }
}
class Person
{
    private int age;

    public void speak()
    {
        System.out.println("age=" + age);
    }
}

【例項 2】:將age私有化以後,類以外即使建立物件也不能直接訪問,但是人應該有年齡,就需要在Person類中提供對應訪問age的方法。

  1. set返回值型別肯定是void,只設置不需要返回值,帶引數。
  2. get沒有引數,只獲取,而且get的返回值型別和獲取的變數一樣。
  3. 一個類裡面在setXXX,getXXX功能,代表這個類裡邊一定有一個私有的屬性XXX。
public class Demo {

    public static void main(String[] args) {
        Person p = new Person();
        p.setAge(20);
        p.speak();

    }
}
class Person
{
    private int age; //一個成員變數,通常會對應兩個訪問方式,一個叫set設定,一個叫get獲取。

    public int getAge() {
        return age;
    }

    /*兩個訪問方式,之所以對外提供訪問方式,就是因為可以在訪問方式中加入邏輯判斷等語句,
    對訪問的資料進行操作,提高程式碼健壯性。
    */
    public void setAge(int age) {
        if(age > 0 && age < 120)
        {
            this.age = age;
        }
    }

    public void speak()
    {
        System.out.println("age=" + age);
    }
}


setAge訪問方式的記憶體分配

【注意】:封裝不是私有,私有僅僅是封裝的一種表現形式,不私有也可以實現封裝,只要許可權在訪問不到的範圍內是封裝的。
     私有許可權是最小的許可權。

類中有多少屬性,一般都需要隱藏起來。

四. 建構函式:

1. 建構函式

建構函式可以過載。
【特點】: 1. 函式名與類名相同。
2. 不用定義返回值型別(與void不同,void是一種返回值型別,代表沒有具體結果返回的情況)
3. 不可以寫return語句,系統也不會加。


public class Demo {

    public static void main(String[] args) {
        Person p = new Person(); //[1]
    }
}

class Person
{
    public Person() //[2]
    {
        System.out.println("Person");
    }
}
/*
輸出結果:Person
[1]和[2]處是一樣的。
所以物件一建立,就會呼叫與之對應的建構函式,new一個就呼叫一次。
*/
【建構函式的作用】: 可以給物件進行初始化,也就是說當在堆記憶體中產生物件的時候,這個物件需要一個初始化動作。
【物件為什麼要初始化】: 現實生活中的事物很多,它只要一出現,就具備基本的特性,
比如,產生一個人,他一出生就會哭,哭是人一出生的行為。
【建構函式的小細節】: 當一個類中沒有定義建構函式時,那麼系統會預設給改類加入一個空引數的建構函式:Person(){ };
加一個後,方便該類初始化,否則物件建立不出來。
在類中自定義了建構函式後,預設的建構函式就沒有了。


【例項 1】:一個類能產生對個物件,而這些物件都可以去呼叫不同的初始化方式。

public class Demo {

    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person("lisi");
        Person p3 = new Person("wangwu", 10);

    }
}

class Person
{
    private String name;
    private int age;

    /*自定義了建構函式後,沒有手動設定空引數的建構函式初始化,new Person()是不可以建立物件的。*/
    public Person()
    {
        System.out.println("A: name=" + name + ", age=" + age);
    }
    public Person(String name)
    {
        this.name = name;
        System.out.println("B: name=" + name + ", age=" + age);
    }
    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
        System.out.println("C: name=" + name + ", age=" + age);
    }
}

【例項 2】:建構函式和一般函式的區別

public class Demo {

    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person("lisi");
        Person p3 = new Person("wangwu", 10);
        p1.setAge(10); //一般函式,被物件呼叫。
    }
}
【建構函式和一般函式的區別】:
1. 建構函式和一般函式在寫法上有不同
2. 執行上有不同 建構函式:是在物件一建立就執行,給物件初始化。
一般函式:是物件呼叫才執行,給物件新增物件具備的功能。

3. 執行次數不同 建構函式:一個物件建立,建構函式只執行一次。
一般函式:可以被物件呼叫多次。

【什麼時候定義建構函式?】:
當分析事物時,該事物存在具備一些特性或者行為,那麼將這些內容定義在建構函式中,
建構函式在定義時,需不需要未知內容參與運算,需要就定義引數,和函式一樣。

【建構函式 + private】:
建構函式是可以被私有化的,因為私有化是來修飾成員的,建構函式也是成員,把建構函式私有化,代表這個類是不可能建立物件的,因為物件都不能進行初始化動作。


2. 構造程式碼塊

構造程式碼塊:定義不同物件共性初始化內容。

【作用】: 給物件進行初始化,物件一建立就執行,而且優先於建構函式執行。

【構造程式碼塊與建構函式區別】: 構造程式碼塊:是給所有物件進行統一初始化
建構函式:是給對應的物件初始化。


public class Demo {

    public static void main(String[] args) {
        Person p = new Person();
    }
}
class Person
{
    private String name;
    private int age;

    {
        System.out.println("構造程式碼塊");
    }

    public Person()
    {
        System.out.println("name=" + name + ", age=" + age);
    }
}

/*【執行結果】:
   構造程式碼塊
   name=null, age=0
*/

五. this關鍵字:

【第一點】: this:看上去是用於區分區域性變數和成員變數同名情況。

【1. this為什麼可以解決這個問題? 2. this到底代表的是什麼?】

=> this就代表本類的物件,this代表它所在函式所屬物件的引用。


【例項 1】:同名區域性變數和成員變數用this

public class Demo {

    public static void main(String[] args) {
        Person p = new Person("張三");
    }
}
class Person
{
    private String name;

    public Person(String name)
    {
        this.name = name; //區域性中有name,在區域性中找name使用,區域性中沒有,就找成員用。
    }
}
/* this.name = name; main 中 Person p = new Person("張三");此處的this就是p物件。
    簡單說,哪個物件在呼叫this所在函式,this就代表哪個物件。
*/

【例項 2】:this省略情況

class Person
{
    private String name;
    private int age;

    public void speak()
    {
        System.out.println("name=" + this.name + ", age=" + this.age);
        //此處this可以省略,但變量出現同名情況,就一定要加。
    }
}
/*在一個類中,成員之前相互呼叫,其實都是物件完成的,而本類中呼叫this,執行的物件,才是被this表示的物件。*/


【第二點】: this:只能用在建構函式間,一般函式不能用。

【this 的應用】:

(1)當定義類中功能時,該函式內部要用到呼叫該函式的物件時,這時用this來表示這個物件。
   但凡本類功能內部使用了本類物件都用this表示。[ 見例項 1 ]

(2)this 語句:用於建構函式之間的相互呼叫,用時要傳相對應的引數。[ 見例項 2 ]


【例項 1】:給人定義一個用於比較年齡是否相同的功能,也就是是否是同齡人。

class Person
{
    private int age;

    public Person(int age)
    {
        this.age = age;
    }

    /**
     * 比較兩人年齡是否相同
     * @param p 傳遞物件
     * @return 返回boolean值
     */
    public boolean compare(Person p)
    {
        return this.age == p.age;
    }
}

public class Demo {

    public static void main(String[] args) {
        Person p1 = new Person(10);
        Person p2 = new Person(20);
        System.out.println(p1.compare(p2)); //p1 和 this是引用物件指向同一物件
    }
}

【例項 2】:建構函式之間的相互呼叫

class Person
{
    private String name;
    private int age;

    public Person(String name)
    {
        this.name = name;
    }

    public Person(String name, int age)
    {
        this(name); //this代表物件,=>p(name) =>new Person(name);給某個物件進行另外的初始化,操作統一物件。
        this.age = age;
    }
}

public class Demo {

    public static void main(String[] args) {
        Person p = new Person("lisi", 20);
    }
}


【第三點】: this:只能定義在建構函式的第一行。(初始化動作要先做)


【例項 1】:this定義在建構函式第一行。

class Person
{
    private String name;
    /* 一個類中有很多種初始化方式,內部初始化方式可以私有起來,只對外暴露一個。*/
    private Person()
    {
    }

    Public Person(String name)
    {
        this();
        this.name = name;
    }
}

【例項 2】:死迴圈

class Person
{
    private String name;

    Public Person()
    {
        this("haha");
    }

    Public Person(String name)
    {
        this();
        this.name = name;
    }
}

六. static關鍵字

1. static(靜態)關鍵字

【用法】: (1)是一個修飾符,用於修飾成員(成員變數,成員函式) static的記憶體分配

【分析】:static靜態修飾的內容,被物件所共享。
     static String country = “cn”;被提取出來,不放在堆記憶體中,每個物件都可以訪問。

(2)當成員被靜態修飾後,就多了一個除錯方法,除了可以被物件呼叫外,還可以直接被類名呼叫
   用法:類名 . 靜態成員

   [e.g.] Person p = new Person();
       System.out.println(p.country); //有物件
     =>System.out.println(Person.country); //沒有物件

【注意】:要區分什麼是共享資料,什麼不共享,不建議定義多個static。

     [e.g.] 飲水機共享,杯子每個人特有不共享。特有內容隨物件儲存。

【特點】: (1)隨著類的載入而載入:

   也就是說,靜態會隨著類的消失而消失,說明它的生長週期最長。
   當類一載入到記憶體中,已經載入在記憶體中了。

  【例項】:
   class Person
   {
     private String name;
     //【非靜態成員變數,例項變數】:物件存在該變數存在;物件不存在,該變數就不存在。

     static String country = “cn”;
     //【靜態成員變數,類變數】:當它存在時,物件還沒存在,所以呼叫時類來呼叫。
   }

(2)優先於物件存在:

   明確一點:靜態是先存在的,物件是後存在的。

(3)被所有物件所共享

(4)可以直接被類名所呼叫

【例項變數和類變數的區別】: (1)存放位置 例項變數:隨著物件的載入而存在於堆記憶體中
類變數:隨著類的載入而存在於方法區中

(2)生命週期 例項變數:隨著物件的消失而消失
類變數:隨著類的消失而存在消失,生命週期最長

【使用注意事項】: (1)靜態方法只能訪問靜態成員。非靜態方法既可以訪問靜態也可以訪問非靜態。

  【例項】:
   public static void show()
   {
     //System.out.println(this.name); //[錯誤]
     //this.speak(); //[錯誤]
   }
   public void speak()
   {
     System.out.println(this.name); //[正確]
     show(); //[正確]
   }

(2)靜態方法中不可以定義this, super關鍵字。
   因為靜態優先存在於物件存在,所以靜態方法中不可以出現this, super。
(3)main主函式是靜態的。

【靜態有利有弊】: 利: 對物件的共享資料進行單獨空間的儲存,節省空間,
沒必要每個物件中儲存一份,可以直接被類名呼叫。
弊: 生命週期過長,訪問出現侷限性(靜態雖好,只能訪問靜態)

【什麼時候使用靜態?】: (1)什麼時候定義靜態變數(類變數):

   當物件中出現共享資料值時,該資料被靜態所修飾,
   物件中的特有資料(姓名是共享屬性而不是共享資料)要定義在非靜態中,存在於堆記憶體中。

(2)什麼時候定義靜態函式:

   當功能內部沒有訪問到非靜態資料(物件特有資料),那麼該功能可以定義成靜態的。


2. 主函式 main

public static void main(String[] args)
主函式是一個特殊的函式,可以被JVM呼叫,作為程式入口。是固定格式。

【主函式的定義】: public: 代表著該函式訪問許可權是最大的。(被JVM訪問)
static: 代表主函式隨著類的載入就已經存在了。
void: 主函式沒有具體的返回值。
main: 不是關鍵字,但是是一個特殊的單詞,可以被JVM識別。
函式引數(String[] args): 引數型別是一個數組,該陣列中的元素是字串,也稱字串型別陣列


【例項】:測試主函式引數長度。main可以過載,但入口只有一個。

public class Demo {
    public static void main(int x) { //可以過載

    }

    public static void main(String[] args) { //程式的入口,先執行,【args引數名】:可以更改,全稱:arguments
        System.out.println(args.length); //結果為0

    }
}
/*引用型別資料,能接收兩種值:null,和具體值
1. String[] args = null;
2. String[] args = new String[2];*/


JVM在呼叫主函式時,傳入的是new String[0],長度為0。

Javac: 啟動底層編譯器。
Java: Java對外提供的功能,啟動底層的JVM,JVM執行Demo這個類,類中的方法被JVM呼叫。
設定主函式的引數: java Demo haha hehe heihei:將類後面跟的這些資料,自動的存入陣列中,即定義長度為3的陣列。
【Demo 】:類名
【haha hehe heihei】:主函式的引數,角標從0開始。


【例項】:JVM呼叫Demo的主函式,Demo呼叫DemoTest的主函式。實現在程式中設定主函式的引數。

public class Demo {

    public static void main(String[] args) { 
        String[] arr = {"x", "y", "z"};
        DemoTest.main(arr);
    }
}
public class DemoTest {

    public static void main(String[] args) { 
        for(int i = 0; i < args.length; i++) //列印主函式引數列表
        {
            System.out.println(args[i]);
        }
    }
}

3. 靜態的應用

每一個應用程式中都有共性的功能,可以將這些功能抽取,獨立封裝,以便複用。

【例項】:將操作資料的功能抽取,放入ArrayTool類中。

 雖然可以通過建立ArrayTool物件使用這些工具方法,對陣列進行操作。

 [發現了問題]:

  1. 物件是用於封裝資料的,可是ArrayTool物件並沒有封裝特有資料。

  2. 運算元組的每一個方法都沒有用到ArrayTool物件中的特有資料。
    => 所以這時就考慮,讓程式更嚴謹,是不需要物件的。
      可以將ArrayTool中的方法都定義成static的,直接通過類名呼叫。

  3. 將方法都靜態後,可以方便於使用,但是該類還是可以被其他程式建立物件的。
    => 所以為了更加謹慎,強制讓該類不能建立物件,避免堆記憶體中出現亂七八糟物件。
      可以將建構函式私有化完成。
public class Demo {

    public static void main(String[] args) {
         int[] arr = {5,1,6,4,2,8,9};
         System.out.println("-------------排序前-------------");
         ArrayTool.printArray(arr);
         ArrayTool.selectSort(arr); //選擇排序
         System.out.println("-------------排序後-------------");
         ArrayTool.printArray(arr);

    }
}

/**
這是一個可以對陣列進行操作的工具類,有獲取最值,排序等功能。
@author 佳露
@version V1.1
*/
public class ArrayTool
{
    /**
     * 私有化空引數建構函式,不能建立實體物件,無法例項化
     */
    private ArrayTool(){}

    /**
     * 獲得陣列最大值max
     * @param arr 陣列
     * @return 最大值
     */
    public static int getMax(int[] arr)
    {
        int max = arr[0];
        for (int i=1; i<arr.length; i++)
        {
            if(max < arr[i])
                max = arr[i];

        }

        return max;
    }

    /**
     * 獲得陣列最小值min
     * @param arr 陣列
     * @return 最小值
     */
    public static int getMin(int[] arr)
    {
        int min = arr[0];
        for (int i=1; i<arr.length; i++)
        {
            if(min > arr[i])
                min = arr[i];

        }

        return min;
    }

    /**
     * 直接插入排序 + 希爾排序 + space取整
     * @param arr 陣列
     */
    public static void shellSort(int[] arr)
    {
        int space = arr.length;
        do
        {
            space >>= 1; // space = space/2;

            for (int i = space; i < arr.length; i++) {  //在直接排序的基礎上,將間隔1,改為space
                if(arr[i] < arr[i-space])
                {
                    int temp = arr[i], j;
                    for (j = i - space; j >= 0 && arr[j] > temp; j -= space) {
                        arr[j + space] = arr[j];
                    }
                    arr[j + space] = temp;
                }
            }

        }while(space > 0);
    }

    /**
     * 直接插入排序 + 希爾排序 + space四捨五入
     * @param arr 陣列
     */
    public static void shellSort2(int[] arr)
    {
        double spaceD = arr.length;
        int space;
        do
        {
            spaceD = Math.ceil(spaceD / 2); //四捨五入
            space = (int)spaceD;

            for (int i = space; i < arr.length; i++) {  //在直接排序的基礎上,將間隔1,改為space
                System.out.println("arr[i-space="+arr[i-space]);
                System.out.println("arr[i]="+arr[i]);
                if(arr[i] < arr[i-space])
                {
                    int temp = arr[i], j;
                    for (j = i - space; j >= 0 && arr[j] > temp; j -= space) {
                        System.out.println("arr[j]="+arr[j]);
                        arr[j + space] = arr[j];
                    }
                    arr[j + space] = temp;
                    printArray(arr);
                }
            }

        }while(space != 1); //由於四捨五入,最後space一定為1
    }

    /**
     * 直接插入排序
     * @param arr 陣列
     */
    public static void insterSort(int[] arr)
    {
        for (int i = 1; i < arr.length; i++) {
            if(arr[i] < arr[i-1])
            {
                int temp = arr[i], j;
                for (j = i - 1; j >= 0 && arr[j] > temp; j--) {
                    arr[j + 1] = arr[j];
                }
                arr[j + 1] = temp;
            }
        }
    }

    /**
     * 氣泡排序
     * @param arr 陣列
     */
    public static void bubbleSort(int[] arr)
    {
        for (int i = 0; i < arr.length - 1; i++) {

            int j = 0, max = 0; //max 記錄最大值的角標

            for (j = 1; j < arr.length - i; j++) {
                if(arr[j] > arr[max])
                {
                    max = j;
                }
            }
            if(j-1 != max) //如果max 角標不等於最後一個角標,兩數交換
            {
                swap(arr, j-1, max); //兩數交換
            }
        }
    }


    /**
     * 選擇排序
     * @param arr 陣列
     */
    public static void selectSort(int[] arr)
    {
        for (int i = 0; i < arr.length - 1; i++) {
            for(int j = i + 1; j < arr.length; j++)
            {
                if(arr[i] > arr[j])
                {
                    swap(arr, i, j); //兩數交換
                }
            }
        }
    }

    /**
     * 交換陣列中的兩個元素
     * @param arr 陣列
     * @param i 陣列角標i
     * @param j 陣列角標j
     */
    private static void swap(int[] arr, int i, int j)
    {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }

    /**
     * 列印陣列
     * @param arr 陣列
     */
    public static void printArray(int[] arr)
    {
        for (int i = 0; i < arr.length; i++) {
            if( i != arr.length -1)
            {
                System.out.print(arr[i] + ", ");
            }
            else
            {
                System.out.println(arr[i]);
            }
        }
    }
}

5. 幫助文件的製作

幫助文件:API文件(應用程式介面)
開始製作程式的說明書,Java的說明書通過文件註釋來完成。

【文件註釋】: [ @author ]:作者
[ @version ]:版本號
[ @param ]:引數
[ @return ]:返回值

【幫助文件的製作】: javadoc -d myhelp -author -version ArrayTool.java

[ -d ]:當前資料夾下
[ myhelp ]:資料夾名

【類修飾符】: private:私有的不被做成說明文件。
public 和 protect(保護)才被做成說明文件。

【預設建構函式的許可權】: 一個類中預設會有一個空引數的建構函式,這個預設的建構函式的許可權和所屬類一致。
如果類被public修飾,那麼預設的建構函式也帶public修飾,如果沒有,則也沒有。
=>預設建構函式的許可權是隨類的變化而變化。


6. 靜態程式碼塊

【格式】: static
{
  靜態程式碼塊中的執行語句;
}

【特點】: 隨著類的載入而執行,只執行一次。用於給類進行初始化的。
一個類進記憶體,不需要物件的情況下,做一些事,優先於主函式,優先於物件。


【例項 1】:static程式碼塊執行過程

public class Demo { // [1]類載入進記憶體

    static // [2]類初始化
    {
        System.out.println("b");
    }

    public static void main(String[] args) {
        new StaticCode();  // [4]類初始化
        new StaticCode();  // [4]類初始化,已經定義了,第二次不再執行。
        System.out.println("over");  // [5]輸出執行
    }

    static // [3]類初始化:優先於主函式
    {
        System.out.println("c");
    }

}
class StaticCode
{
    static // [4]類初始化
    {
        System.out.println("a");
    }
}

/*[輸出結果]:b c a over*/

【例項 2】:static程式碼塊可以驗證類有無載入

public class Demo {

    public static void main(String[] args) {
        //[1] 
        //StaticCode.show(); // 載入了類,[輸出結果]: a  show run

        //[2]
        //StaticCode sc = new StaticCode();// 載入了類,用的了構造方法。 [輸出結果]: a

        //[3]
        //StaticCode sc = null;// 沒有載入類,sc沒有指向。 [輸出結果]: (沒有輸出)

        /*用到類中的內容,才載入類。*/
    }

}
class StaticCode
{
    static
    {
        System.out.println("a");
    }

    public static void show()
    {
        System.out.println("show run");
    }
}

【例項 3】:建構函式(有無引數),構造程式碼塊,靜態程式碼塊執行過程

public class Demo {

    public static void main(String[] args) {
        StaticCode sc = new StaticCode(4);  // 類載入,呼叫有參建構函式。
    }

}
class StaticCode 
{
    int num = 9;

    /**
     * 無參建構函式,初始化對應物件
     */
    public StaticCode() 
    {
        System.out.println("b");
    }

    /**
     * 帶引數建構函式,初始化對應物件  [3] 對應物件初始化
     */
    public StaticCode(int x) 
    {
        System.out.println("d");
    }

    /**
     * 靜態程式碼塊,初始化類  [1] 類初始化
     */
    static 
    {
        System.out.println("a");
    }

    /**
     * 構造程式碼塊,初始化物件  [2] 所有物件初始化
     */
    {
        System.out.println("c" + this.num);
    }
}

/*[輸出結果]:a c9 d*/

7. 物件建立,物件呼叫非靜態方法記憶體分配

【例項】:分析以下程式碼的記憶體分配情況

public class Demo {

    public static void main(String[] args) {
        Person p = new Person("zhangshan", 20);
    }

}
class Person
{
    private String name = "haha";
    private int age;
    private static String country = "CN";

    public Person(String name, int age)
    {
         this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public 
            
           

相關推薦

Java 007 面向物件構造方法、static關鍵字、JDK幫助、Math

知識點梳理 心得體會 小知識點 1.不同型別的靜態變數 1>靜態變數是基本資料型別時,類的外部不用建立該類例項可以能直接使用 2>靜態變數是引用時,即靜態變數是一個物件的引用,必須先初始化這個物件,才能將引用指向靜態變數 2.靜態成員與例項成員 1&

面向物件_成員變數_ 區域性變數_匿名物件_封裝_建構函式_構造程式碼

----------- android培訓、java培訓、java學習型技術部落格、期待與您交流! ------------ 【面向物件】面向物件有三個特徵:封裝,繼承,多型 面向物件的特點:找物件,建物件,用物件,多型完了之後維護物件之間的關係 類和對像的關係:類就是對現

將CHM檔案轉換成html檔案、將jdk幫助加入到eclipse中jdk1.8中文幫助下載

一、將CHM檔案轉換成html檔案 1.下載相關的CHM檔案,如:我下載的是jdk1.8幫助文件(中文版),需要的自行下載,我已儲存到我的百度網盤了,連結在最下方。 注:個人建議下載谷歌版的,可以參考下方這張圖: 2.將whm檔案下載到D盤的jdkap

Java基礎---面向物件面向物件物件匿名物件封裝建構函式構造程式碼thisstaticmain幫助靜態程式碼

一. 面向物件概念: 面向物件其實是一種思考的思想,早期思想是面向過程。 面向過程注重的是過程,過程所涉及的行為,也就是功能。 【例項】:面向過程: 1. 把冰箱開啟 2. 把大象放入 3. 冰箱關起來      面向物件: 開啟冰箱,儲存,關閉都是對冰箱的操作,是冰箱的行為

Java設計模式餓漢懶漢和多設計模式

1.單例模式 定義:一個類只允許產生一個例項化物件。 a.物件如何產生? 通過類的構造方法 b.要想限制物件的產生? 通過構造方法限制,構造方法私有化,類外部無法產生例項化物件。 餓漢式單例:上來就new //餓漢式單例 class Singleton{

java基礎知識整理 ---Day06面向物件

一、程式語言的發展 機器語言 直接由計算機的指令組成,指令、資料、地 址都以“0”和“1”組成:可以被計算機直接識別並執行。 組合語言 用容易理解和記憶的符號表示指令、資料以 及暫存器等,抽象層次很低,程式設計師需要考慮大量的機器細節。 高階語言 遮蔽了機器細節,

java:面向物件學生和老師的繼承練習

package Day08; public class Demo8_Person { public static void main(String[]args){ Studen

JAVA之類建構函式構造程式碼

類:         在我們的日常生活中,對於事物的描述無非就是描述事物的屬性和行為。如:人的身高,體重,年齡等稱為屬性,人會說話,會跑步,會做飯等等稱為行為。         而對於Java中的類,無非也是如此,包含了屬性和行為。 類的定義: 屬性:對應類中的成員變數行

Java基礎-第六章(面向物件5)

一、介面 (一) 介面的定義和使用 多個抽象類的抽象就是介面。 在Java中最小的程式單元就是類,介面其實是一個特殊的類。 Java中的介面表示規範,用於定義一組抽象方法,表示某一類事物必須具備的功能,要求實現類必須來實現介面並提供方法實現。 定義

python讀寫Excel--使用xlrd模讀取xlwt模寫入

xlrd get sta series 有趣 light log 分享 均值 一、安裝xlrd模塊和xlwt模塊 1. 下載xlrd模塊和xlwt模塊 到python官網http://pypi.python.org/pypi/xlrd下載模塊。下載的文件

JPA hibernate spring repository pgsql java 工程:sql導入數據測試數據

ber tracking evel 主鍵 出現 一個 OS resources pos 使用jpa保存查詢數據都很方便,除了在代碼中加入數據外,可以使用sql進行導入。目前我只會一種方法,把數據集中在一個sql文件中。 而且數據在導入中常常具有先後關系,需要用串行的方式導

Django部署生產環境靜態不能訪問404以及圖片不能訪問403

以及 數據 col debug client localhost char clear IE 部署環境的搭建請看此博客https://blog.csdn.net/anifans9350/article/details/80145535 查看nginx.conf 文件,

架起線上線下存儲橋梁雲存儲網關開放性能型網關及網關公測

存儲 安全 摘要: 雲存儲網關支持行業標準的文件和塊存儲協議,可以通過在本地緩存經常訪問的數據來提供低延遲高性能, 讓企業或個人安全地將數據存儲在阿裏雲OSS中,最新發布的“性能型文件網關”和“塊網關”現已開通公測。為助力企業實現線下本地存儲及雲上存儲空間的無縫連接,阿裏雲在去年6月推出雲存儲網關產品

mybatis源碼-解析配置之配置Configuration解析(超詳細 值得收藏)

類型 version 創建對象 越來越大 ... 所有 類名 對象 and 1. 簡介 1.1 系列內容 本系列文章講解的是mybatis解析配置文件內部的邏輯, 即 Reader reader = Resources.getResourceAsReader("mybat

17 的打開模式和文對象的方法

操作 lose 可叠代對象 移動 from 位置 cells adl center                     文件打開模式 打開模式 執行操作 ‘r‘ 以只讀方式打開文件(默認) ‘w‘ 以寫入的方式打開文件,會覆蓋已存

java基礎學python----------字典集合

字典 類似於java中的hashmap 建立字典  使用{}建立字典  使用:指明鍵:值對 my_dict = {'John': 86411234, 'Bob': 86419453,'Mike': 86412387}  鍵必須是不可變的且不重複,值可以是

java基礎學python--------列表元組

 列表:相當於java中的list用法 下標用法與python中的字串相似也可以用-1等負數來表示 也可以使用*重複用法 可以使用in關鍵字用法 也可以求長度:len(list) for迴圈可以遍歷表內元素 列表的方法: 賦值與java中相似,python中可以用切片的方式給

軟體工程之程式編碼④原始碼“化”:識別符號命名註釋程式視覺組織

      編碼的目的是使用選定的程式設計語言,把模組的過程描述翻譯為用該語言書寫的源程式。源程式應該正確可靠、簡明清晰,而且具有較高的效率。軟體工程專案對程式碼編寫的要求,不僅僅是源程式語法上的正確性,也不只是源程式中沒有各種錯誤,還要求源程式具有良好的結構性和良好的

Java基礎面試題5----StringStringBufferStringBulider的區別

問題 說明String和StringBulider的區別? 說明StringBulider和StringBuffer的區別 解析 1. 首先String和StringBuilder的區別 在java中提供了三個類String,StringBuffer,Str

Java基礎面試題12----JSP是什麼和內建物件介紹

問題 JSP和Servlet有什麼區別? JSP有哪些內建物件,他們的作用是什麼? 解析1:JSP和Servlet又有什麼區別? JSP和Servlet的關係 我們上次講解Servlet的時候,去看了他的原始碼,最終實現的是Servlet介面。而JSP