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

                                       面向對象

注:java

看此篇時強烈建議有必定的面向對象思想基礎,有必定的基礎後先翻到下面看第九條:
      9.面向對象: 從未封裝→封裝→繼承→多態→抽象類→接口的代碼演變編程

按這個邏輯去看,,哪有不理解的再回頭看知識點,這是掌握理解最好最快的方法,切記切記ide

 

萬物皆對象this

            描述一個物質均可以經過兩方面說明:數據模型(屬性)、行爲模型(行爲)。spa

            在Java編程中,咱們使用成員變量表示數據模型,用成員方法表示行爲模型。線程

            使用表示某些具備相同屬性和行爲的事物。code

 

1. 方法:對象

        構造方法     blog

                     語法:繼承

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

                  注意:

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

                           若是類中有顯示的構造方法,程序就不會建立無參構造;

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

        靜態方法

                       static 關鍵字用來聲明獨立於對象的靜態方法。靜態方法不能使用類的非靜態變量。靜態方法從參數列表獲得數據,而後計算這些數據。

                  對類變量和方法的訪問能夠直接使用 classname.variablename 和 classname.methodname 的方式訪問。

 

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

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

  

        成員方法(實例方法)

2. 變量:

        成員變量(實例變量)

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

        局部變量                      

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

        靜態變量(類的變量)

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

 

3. 修飾符

        訪問修飾符      

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

      • default (即缺省,什麼也不寫): 在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。

      • private : 在同一類內可見。使用對象:變量、方法。 注意:不能修飾類(外部類)

      • public : 對全部類可見。使用對象:類、接口、變量、方法

      • protected : 對同一包內的類和全部子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)

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

 修飾符 當前類 同包的類 同包的子孫類 異包類 異包的子孫類
public 
protected × ×
default × ×
private × × × ×

 

          非訪問修飾符

                     爲了實現一些其餘的功能,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(){
          .........
      }
}

 

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

                                    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,因此該循環會中止。

 

4. this關鍵字

                           this指當前對象,用法:

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

 

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

5. 封裝

                             私有的屬性,公開的方法。

                             封裝的步驟:

                                    聲明私有(private)的屬性;

                                    聲明公開(public)的geter和seter方法;

6. 繼承

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

                語法:

public class Son extends Father{

 

}

  

               規則:

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

                重寫定義:

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

7. 多態

                實現的必要條件:

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

 

                              instanceof關鍵字:

 

語法:
if (對象名 instanceof 類名) {		
			類型轉換代碼;
}

 

  

實例:
Animal cat = new Cat();
		if (cat instanceof Cat) {//返回結果爲boolean類型
			Cat c = (Cat) cat;
			c.eat();
		}else{
			System.out.println("類型不匹配");
		}

8. 接口

語法:
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();//執行類中的方法
    }
}

運行結果:
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打印

10. 內部類

               成員內部類

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

 

語法:
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(){
		};
	}
}

  

 

相關文章
相關標籤/搜索