Java匹馬行天下之JavaSE核心技術——面向對象

Java匹馬行天下之JavaSE核心技術——面向對象

注:看此篇時強烈建議有必定的面向對象思想基礎,有必定的基礎後先翻到下面看第九條:9.面向對象: 從未封裝→封裝→繼承→多態→抽象類→接口的代碼演變,按這個邏輯去看,哪有不理解的再回頭看知識點,這是掌握理解最好最快的方法,切記切記javascript

萬物皆對象

描述一個物質均可以經過兩方面說明:數據模型(屬性)、行爲模型(行爲)。在Java編程中,咱們使用成員變量表示數據模型,用成員方法表示行爲模型。使用類表示某些具備相同屬性和行爲的事物。html

一、函數

構造函數:

語法:java

[訪問修飾符] 類名(){ }編程

做用:ide

構造函數,通常是用於爲成員屬性賦初始化值;函數

注意:this

  • 當類中沒有顯式的構造方法,實例化該類的對象時,程序會自動建立一個公開的無參構造方法;
  • 若是類中有顯示的構造方法,程序就不會建立無參構造;

靜態函數:

  • static關鍵字用來聲明獨立於對象的靜態方法。靜態方法不能使用類的非靜態變量。靜態方法從參數列表獲得數據,而後計算這些數據。
  • 對類變量和方法的訪問能夠直接使用 classname.variablename 和 classname.methodname 的方式訪問。

以下例所示,static修飾符用來建立類方法和類變量:spa

public class InstanceCounter {
   private static int numInstances = 0;
   protected static int getCount() {
      return numInstances;
   }

   private static void addInstance() {
      numInstances++;
   }

   InstanceCounter() {
      InstanceCounter.addInstance();
   }

   public static void main(String[] arguments) {
      System.out.println("Starting with " +
      InstanceCounter.getCount() + " instances");
      for (int i = 0; i < 500; ++i){
         new InstanceCounter();
          }
      System.out.println("Created " +
      InstanceCounter.getCount() + " instances");
   }
}

運行結果:線程

Starting with 0 instances
Created 500 instances

成員函數(實例函數)

二、變量

成員變量(實例變量)

  • 聲明在全部方法體和代碼塊以外,而且沒有使用static修飾的變量,叫作實例變量;
  • 可使用訪問修飾符和final修飾;
  • 使用final修飾時,必定要賦值;
  • 實例變量是在對象被建立時建立,對象被銷燬時銷燬;
  • 做用域範圍在整個類中;

局部變量

  • 聲明在構造方法、靜態方法、實例方法、代碼塊中的變量,都是局部變量;
  • 不能使用static和訪問修飾符修飾;
  • 可使用final修飾,即爲常量,沒必要在聲明語句中賦值;
  • 當執行局部變量所在的方法或代碼塊時,纔有機會被建立,在方法或代碼塊執行結束後被自動銷燬;
  • 局部變量在內存的棧區分配;
  • 局部變量在使用以前必需要先賦值;

靜態變量(類的變量)

  • 聲明在全部方法體和代碼塊以外,而且使用static修飾的變量;
  • 可使用訪問修飾符修飾;
  • 通常配合final使用,即public static fianl,標識符使用大寫;
  • 類變量被分配在靜態存儲區,是被全部該類的對象共享數據;
  • 類變量是在程序開始時被建立,程序結束時銷燬;

三、修飾符

訪問修飾符

Java中可使用訪問控制符來保護對類、變量、方法和構造方法的訪問。Java 支持 4 種不一樣的訪問權限。code

  • default (即缺省,什麼也不寫): 在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。
  • private : 在同一類內可見。使用對象:變量、方法。 注意:不能修飾類(外部類)
  • public : 對全部類可見。使用對象:類、接口、變量、方法
  • protected : 對同一包內的類和全部子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)

咱們能夠經過如下表來講明訪問權限:

非訪問修飾符

爲了實現一些其餘的功能,Java 也提供了許多非訪問修飾符。

  • static 修飾符,用來修飾類方法和類變量。
  • final 修飾符,用來修飾類、方法和變量,final 修飾的類不可以被繼承,修飾的方法不能被繼承類從新定義,修飾的變量爲常量,是不可修改的。

final修飾變量:

  • final 表示"最後的、最終的"含義,變量一旦賦值後,不能被從新賦值。被 final 修飾的實例變量必須顯式指定初始值。
  • final 修飾符一般和 static 修飾符一塊兒使用來建立類常量。
//實例
public class Test{
  final int value = 10;
  // 下面是聲明常量的實例
  public static final int BOXWIDTH = 6;
  static final String TITLE = "Manager";

  public void changeValue(){
     value = 12; //將輸出一個錯誤
  }
}

final修飾方法:

  • 類中的 final 方法能夠被子類繼承,可是不能被子類修改。
  • 聲明 final 方法的主要目的是防止該方法的內容被修改。

以下所示,使用 final 修飾符聲明方法:

public class Test{
    public final void changeName(){
       // 方法體
    }
}

final修飾類:

  • final 類不能被繼承,沒有類可以繼承 final 類的任何特性。
//實例
public final class Test {
   // 類體
}

注意:

  • 當final修飾類時,當前類不能被繼承;
  • 當final修飾方法時,該方法不能被重寫;
  • 當final修飾變量時,變量的值不能被修改,即爲常量;

abstract修飾符,用來建立抽象類和抽象方法。
抽象類:

  • 抽象類不能用來實例化對象,聲明抽象類的惟一目的是爲了未來對該類進行擴充。
  • 一個類不能同時被 abstract 和 final 修飾。若是一個類包含抽象方法,那麼該類必定要聲明爲抽象類,不然將出現編譯錯誤。
  • 抽象類能夠包含抽象方法和非抽象方法。

規則:

  • 含有抽象方法的類,必定是抽象類;
  • 抽象類中能夠聲明成員變量、常量、成員方法、抽象方法,抽象類中不必定要有抽象方法;
  • 抽象類不能被實例化;
  • 抽象類能夠被繼承;
  • 能夠經過兩種方式得到抽象類對象:父類引用指向子類對象、匿名內部類;
  • 子類必須重寫抽象父類的全部抽象方法,或者是把子類也定義爲抽象類;
  • 若是一個類繼承的抽象父類還有上級抽象父類,那麼子類中須要要重寫全部抽象父類的全部抽象方法;
  • 抽象類也能夠繼承非抽象類,同時繼承了父類的全部非私有的屬性和方法;

實例:

abstract class Caravan{
   private double price;
   private String model;
   private String year;
   public abstract void goFast(); //抽象方法
   public abstract void changeColor();
}

抽象方法

  • 抽象方法是一種沒有任何實現的方法,該方法的的具體實現由子類提供。
  • 抽象方法不能被聲明成 final 和 static。
  • 任何繼承抽象類的子類必須實現父類的全部抽象方法,除非該子類也是抽象類。
  • 若是一個類包含若干個抽象方法,那麼該類必須聲明爲抽象類。抽象類能夠不包含抽象方法。
    *抽象方法的聲明以分號結尾,例如:public abstract sample();

實例:

public abstract class SuperClass{
    abstract void m(); //抽象方法
}

class SubClass extends SuperClass{
     //實現抽象方法
      void m(){
          .........
      }
}

synchronizedvolatile 修飾符,主要用於線程的編程。

synchronized 修飾符

synchronized 關鍵字聲明的方法同一時間只能被一個線程訪問。synchronized 修飾符能夠應用於四個訪問修飾符。

實例
public synchronized void showDetails(){
.......
}

transient 修飾符

  • 序列化的對象包含被 transient 修飾的實例變量時,java 虛擬機(JVM)跳過該特定的變量。
  • 該修飾符包含在定義變量的語句中,用來預處理類和變量的數據類型。
實例
public transient int limit = 55;   // 不會持久化
public int b; // 持久化

**volatile **修飾符

  • volatile 修飾的成員變量在每次被線程訪問時,都強制從共享內存中從新讀取該成員變量的值。並且,當成員變量發生變化時,會強制線程將變化值回寫到共享內存。這樣在任什麼時候刻,兩個不一樣的線程老是看到某個成員變量的同一個值。
  • 一個 volatile 對象引用多是 null。
實例
public class MyRunnable implements Runnable
{
    private volatile boolean active;
    public void run()
    {
        active = true;
        while (active) // 第一行
        {
            // 代碼
        }
    }
    public void stop()
    {
        active = false; // 第二行
    }
}

一般狀況下,在一個線程調用 run() 方法(在 Runnable 開啓的線程),在另外一個線程調用 stop() 方法。 若是 第一行 中緩衝區的 active 值被使用,那麼在 第二行 的 active 值爲 false 時循環不會中止。可是以上代碼中咱們使用了 volatile 修飾 active,因此該循環會中止。

四、關鍵字

this指當前對象,用法:

  • 當局部變量名和實例變量名同名時,使用this.變量名來表示實例變量;
  • this()表示當前類的構造方法,只能在構造方法中使用該寫法,而且是寫在構造方法內的第一行。

面向對象三大特徵:封裝、繼承、多態

五、封裝

私有的屬性,公開的方法。
封裝的步驟:

  • 聲明私有(private)的屬性;
  • 聲明公開(public)的geter和seter方法;

六、繼承

Java中的繼承是單繼承,能夠實現多層繼承,繼承的關鍵字extends

語法:

public class Son extends Father{

}

規則:

  • 子類繼承父類非私有的全部屬性和方法,不能繼承父類的構造方法;
  • 實例化子類對象的步驟:先執行父類的構造方法,再執行子類的構造方法;

重寫定義:

  • 子類從新聲明從父類繼承來的方法,稱爲方法重寫;
  • 方法重寫時,方法的聲明部分要和父類保持一致(返回值類型,方法名,參數);
  • 重寫方法的訪問權限要大於等於父類中方法的訪問權限;
  • 子類重寫父類方法,子類對象調用的是子類中重寫後的方法;
  • 使用static修飾的方法不能被重寫,可是能夠被子類重寫聲明;
  • 不一樣包的子類能夠重寫父類中protected修飾的方法,可是不能以繼承的形式,用子類對象直接調用父類的該方法;

七、多態

實現的必要條件:

  • 繼承
  • 重寫
  • 父類引用指向子類對象

instanceof關鍵字:

語法:
if (對象名 instanceof 類名) {       
            類型轉換代碼;
}
實例:
Animal cat = new Cat();
        if (cat instanceof Cat) {//返回結果爲boolean類型
            Cat c = (Cat) cat;
            c.eat();
        }else{
            System.out.println("類型不匹配");
        }

八、接口

語法:
public interface ITest {

}

規則:

  • 接口使用interface關鍵字修飾;
  • 接口是一個徹底抽象的抽象類;
  • 接口中沒有構造方法;
  • 接口不能被實例化對象;
  • 接口中能夠聲明靜態常量、抽象方法、靜態方法;
  • 接口中不能聲明實例方法,聲明抽象方法時,不能使用static關鍵字修飾;
  • 聲明接口語句中,默認含有abstract關鍵字,抽象方法中也默認含有abstract關鍵字;
  • 接口能夠被實現,使用implements關鍵字,一個類實現一個接口,必須重寫該接口中全部的抽象方法;
  • 一個類能夠實現多個接口,每一個接口名用英文的逗號隔開,該類中必須重寫全部已實現接口中的抽象方法;
  • 接口能夠繼承接口,接口與接口間是多繼承關係,接口不能繼承類;

9.面向對象: 從未封裝→封裝→繼承→多態→抽象類→接口的代碼演變:

未封裝:

public class Person {
    int age;//年齡
    String name;//姓名
    public void print()
    {
        System.out.println("age:"+this.age+" "+"name:"+this.name);
    }
}

class Text{
    public static void main(String[] args) {
        Person person = new Person();//實例化對象
        person.age = -100;//賦值
        person.name = "張三";
        person.print();//執行類中的方法
    }
}


運行結果:<br>age:-100 name:張三

封裝:

public class Person {
    private int age;//年齡
    private String name;//姓名

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

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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + this.age +
                ", name='" + this.name + '\'' +
                '}';
    }
}


class Text{
    public static void main(String[] args) {
        Person person = new Person();
        person.setAge(20);
        person.setName("張三"); ;
        String s = person.toString();
        System.out.println(s);
    }
}


運行結果:
Person{age=20, name='張三'}

繼承

public class Office {
    public void print(){
        System.out.println("打印");
    }
}

class Word extends Office {
    @Override
    public void print() {
        System.out.println("Word打印");
    }
}

class Test{
    public static void main(String[] args) {
        Word word = new Word();
        word.print();
    }
}

運行結果:
Word打印

一個Java源文件中能夠聲明多個class類,但只能有一個public修飾的類。

多態

public class Office {
    public void print(){
        System.out.println("打印");
    }
}

class Word extends Office {
    @Override
    public void print() {
        System.out.println("Word打印");
    }
}

class Excle extends Office{
    @Override
    public void print() {
        System.out.println("Excel打印");
    }
}

class  Ppt extends Office{
    public void daYin() {//子類能夠重寫父類方法,也能夠本身定義方法
        System.out.println("PPT打印");
    }
}

class Test{
    public static void main(String[] args) {
        Office o = new Word();//多種形態,即多態
        o.print();
    }
}

運行結果:

Word打印

class Test{
    public static void main(String[] args) {
        Office o = new Excle();
        o.print();
    }
}

運行結果:

Excel打印

class Test{
    public static void main(String[] args) {
        Office o = new Ppt();
        o.print();
    }
}

運行結果:

打印

爲避免這種方法名稱多樣的狀況,用一種約束叫抽象類

public abstract class Office {
    public abstract void print();
}

class Word extends Office {
    @Override
    public void print() {
        System.out.println("Word打印");
    }
}

class Excle extends Office{
    @Override
    public void print() {
        System.out.println("Excel打印");
    }
}

class  Ppt extends Office{
    @Override
    public void print() {
        System.out.println("PPT打印");
    }
}

class Test{
    public static void main(String[] args) {
        Office o = new Ppt();//父類引用指向子類對象,子類重寫父類方法,父類引用調用子類重寫後的方法,執行的結果是子類重寫後的方法
        o.print();
    }
}

運行結果:

PPT打印

接口是徹底抽象的抽象類,而且能夠多實現

接口默認爲:
public  class abstract interface Office {
    public abstract  void print();
}
---------------------------------------------------------
public interface Office {
    void print();
}

class Word implements Office {
    @Override
    public void print() {
        System.out.println("Word打印");
    }
}

class Excle implements Office{
    @Override
    public void print() {
        System.out.println("Excel打印");
    }
}

class  Ppt implements Office{
    @Override
    public void print() {
        System.out.println("PPT打印");
    }
}

class Test{
    public static void main(String[] args) {
        Office o = new Ppt();
        o.print();
    }
}

運行結果爲:

PPT打印

十、內部類

成員內部類

成員內部類聲明在類中,方法體、代碼塊以外。和成員變量、成員方法在同一級別。

語法:
public class Out {
      //成員內部類
      public class Inner{
      }
}

實例化成員內部類:
        //先實例化外部類
        Out o = new Out();
        //使用外部類對象,再實例化內部
        Out.Inner inner = o.new Inner();

實例:
public class Out {
    //成員變量
    public int a = 1;

    //成員內部類
    public class Inner{
        public int a = 2;
        //內部類的成員方法
        public void print(){
//執行內部類中的實例變量a
            System.out.println(a);
//執行外部類的實例變量a
            System.out.println(Out.this.a);    
}
    }
}

靜態內部類

聲明的位置參考成員內部類。

語法:
public class Out {
    //靜態內部類
    public static class Inner{

    }
}

實例化靜態內部的對象:
Out.Inner inner = new Out.Inner();

實例:
public class Out {
    public static int a = 1;
    public int b = 3;
    //靜態內部類
    public static class Inner{
        public static int a = 2;
        public static void print(){
            //執行靜態內部的靜態變量
            System.out.println(a);
            //執行外部類的靜態變量
            System.out.println(Out.a);
            //執行外部類的實例變量
            Out o = new Out();
            System.out.println(o.b);
        }
    }
}

局部內部類

聲明在方法體或代碼塊內,做用域範圍在方法體或代碼塊內。

語法:
public class Out {
    public void method(){
        //局部內部類
        class Inner{
            //局部內部類的成員方法
            public void print(){
                System.out.println("局部內部類");
            }
        }
        //實例化局部內部類
        Inner inner = new Inner();
        inner.print();
    }
}

執行局部內部類的方法:
Test類:
public static void main(String[] args) {
        Out o  = new Out();
        o.method();
}

匿名內部類

  • 聲明位置同局部內部類同樣,前提條件:必須繼承一個類或實現一個接口,匿名內部類的聲明和實例化對象是同時進行的;
  • 通常使用於得到抽象類或接口對象;
語法:
父類名/接口名  對象名 =  new  父類名/接口名(){
        //匿名內部類成員
};

實例:
父類
public class Father {
}

匿名內部類:
public class Out {
    public void method(){
        //匿名內部類對象
        Father f = new Father(){
        };
    }
}

此篇完

這一篇對新手是不友好的,不過對一些只知其一;不知其二的或者想複習的朋友可能幫助更大。

推薦閱讀

相關文章
相關標籤/搜索