JAVA物件導向思想

一年都在冬眠發表於2024-08-16

封裝

一、概念

封裝(英語:Encapsulation)是指一種將抽象性函式介面的實現細節部分包裝、隱藏起來的方法。封裝可以被認為是一個保護屏障,防止該類的程式碼和資料被外部類定義的程式碼隨機訪問。要訪問該類的程式碼和資料,必須透過嚴格的介面控制。封裝最主要的功能在於我們能修改自己的實現程式碼,而不用修改那些呼叫我們程式碼的程式片段。適當的封裝可以讓程式碼更容易理解與維護,也加強了程式碼的安全性。

二、實現JAVA封裝的步驟

1、修改屬性的可見性來限制對屬性的訪問(一般限制為private)

public class Person {
    private String name;
    private int age;
}

2、對每個值屬性提供對外的公共方法訪問,也就是建立一對賦取值方法,用於對私有屬性的訪問

public class Person{
    private String name;
    private int age;
​
    public int getAge(){
      return age;
    }
​
    public String getName(){
      return name;
    }
​
    public void setAge(int age){
      this.age = age;
    }
​
    public void setName(String name){
      this.name = name;
    }
}

採用this關鍵字是為了解決例項變數(private String name)和區域性變數(setName(String name)中的name變數)之間發生的同名的衝突

三、封裝例項

/* 檔名: EncapTest.java */
public class EncapTest{
 
   private String name;
   private String idNum;
   private int age;
 
   public int getAge(){
      return age;
   }
 
   public String getName(){
      return name;
   }
 
   public String getIdNum(){
      return idNum;
   }
 
   public void setAge( int newAge){
      age = newAge;
   }
 
   public void setName(String newName){
      name = newName;
   }
 
   public void setIdNum( String newId){
      idNum = newId;
   }
}

public方法是外部類訪問該類成員變數的入口,通常情況下,這些方法被稱為getter和setter方法,因此,任何要訪問類中私有成員變數的類都要透過這些getter和setter方法。

/* F檔名 : RunEncap.java */
public class RunEncap{
   public static void main(String args[]){
      EncapTest encap = new EncapTest();
      encap.setName("James");
      encap.setAge(20);
      encap.setIdNum("12343ms");
 
      System.out.print("Name : " + encap.getName()+ 
                             " Age : "+ encap.getAge());
    }
}

Name : James Age : 20

繼承

一、概念

1、 繼承就是子類繼承父類的特徵和行為,使得子類物件(例項)具有父類的例項域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。繼承使程式碼更加簡潔,提高程式碼的複用性(複用性主要是可以多次使用,不會再多次寫同樣的程式碼),維護性也提高。
2、類的繼承格式
透過extends關鍵字可以申明一個類是從另外一個類繼承而來的

class 父類 {
}
 
class 子類 extends 父類 {
}

3、繼承型別

  • Java不支援多繼承(即不支援一個類繼承多個類),但支援多重繼承
  • Java支援不同類繼承同一個類
    4、繼承特性
  • 子類擁有父類非private的屬性、方法
  • 子類可以擁有自己的屬性和方法,即子類可以對父類進行擴充套件
  • 子類可以用自己的方式實現父類的方法
  • 提高了類之間的耦合性(繼承的缺點,耦合度高就會造成程式碼之間的聯絡越緊密,程式碼獨立性越差)

二、繼承關鍵字

1、extends關鍵字
在Java中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,所以extends只能繼承一個類
2、implements關鍵字
使用implements關鍵字可以變相的使java具有多繼承的特性,使用範圍為類繼承介面的情況,可以同時繼承多個介面(介面跟介面之間採用逗號分隔)

public interface A {
    public void eat();
    public void sleep();
}
 
public interface B {
    public void show();
}
 
public class C implements A,B {
}

3、super與this關鍵字

  • super關鍵字:我們可以透過super關鍵字來實現對父類成員的訪問,用來引用當前物件的父類
  • this關鍵字:指向自己的引用,引用當前物件,即它所在的方法或建構函式所屬的物件例項
class Animal {
    void eat() {
        System.out.println("animal : eat");
    }
}
 
class Dog extends Animal {
    void eat() {
        System.out.println("dog : eat");
    }
    void eatTest() {
        this.eat();   // this 呼叫自己的方法
        super.eat();  // super 呼叫父類方法
    }
}
 
public class Test {
    public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        Dog d = new Dog();
        d.eatTest();
    }
}
animal : eat
dog : eat
animal : eat

4、final關鍵字
final可以用來修飾變數(包括類屬性、物件屬性、區域性變數和形參)、方法(包括類方法和物件方法)和類。使用final關鍵字宣告類,就是把類定義定義為最終類,不能被繼承,或者用於修飾方法,該方法不能被子類重寫。
final class 類名 {//類體}
修飾符(public/private/default/protected) final 返回值型別 方法名(){//方法體}

  • final定義的類,其中的屬性、方法不是final的

三、構造器(構造方法、建構函式)

子類是不繼承父類的構造器的,它只是呼叫(隱式或顯式)。如果父類的構造器帶有引數,則必須在子類的構造器中顯式地透過super關鍵字呼叫父類的構造器並配以適當的引數列表。如果父類構造器沒有引數,則在子類的構造器中不需要使用super關鍵字呼叫父類構造器,系統會自動呼叫父類的無參構造器。

class SuperClass {
    private int n;
 
    // 無引數構造器
    public SuperClass() {
        System.out.println("SuperClass()");
    }
 
    // 帶引數構造器
    public SuperClass(int n) {
        System.out.println("SuperClass(int n)");
        this.n = n;
    }
}
 
// SubClass 類繼承
class SubClass extends SuperClass {
    private int n;
 
    // 無引數構造器,自動呼叫父類的無引數構造器
    public SubClass() {
        System.out.println("SubClass()");
    }
 
    // 帶引數構造器,呼叫父類中帶有引數的構造器
    public SubClass(int n) {
        super(300);
        System.out.println("SubClass(int n): " + n);
        this.n = n;
    }
}
 
// SubClass2 類繼承
class SubClass2 extends SuperClass {
    private int n;
 
    // 無引數構造器,呼叫父類中帶有引數的構造器
    public SubClass2() {
        super(300);
        System.out.println("SubClass2()");
    }
 
    // 帶引數構造器,自動呼叫父類的無引數構造器
    public SubClass2(int n) {
        System.out.println("SubClass2(int n): " + n);
        this.n = n;
    }
}
 
public class TestSuperSub {
    public static void main(String[] args) {
        System.out.println("------SubClass 類繼承------");
        SubClass sc1 = new SubClass();
        SubClass sc2 = new SubClass(100);
 
        System.out.println("------SubClass2 類繼承------");
        SubClass2 sc3 = new SubClass2();
        SubClass2 sc4 = new SubClass2(200);
    }
}
------SubClass 類繼承------
SuperClass()
SubClass()
SuperClass(int n)
SubClass(int n): 100
------SubClass2 類繼承------
SuperClass(int n)
SubClass2()
SuperClass()
SubClass2(int n): 200

多型

一、概念
1、多型就是同一個介面,使用不同的例項而執行不同操作。
2、多型性是物件多種表現形式的體現。現實中,比如我們按下F1 鍵這個動作:

  • 如果當前在Flash介面下彈出的就是AS 3的幫助文件;
  • 如果當前在Word下彈出的就是Word幫助;
  • 在Windows下彈出的就是Windows幫助和支援。

同一個事件發生在不同的物件上會產生不同的結果。
3、多型的優點:消除型別之間的耦合關係;可替換性;可擴充性;介面性;靈活性;簡化性。
4、多型存在的三個必要條件:繼承;重寫;父類引用指向物件
Parent p = new Child()
5、當使用多型方式呼叫方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,再去呼叫子類的同名方法
6、例項

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 物件呼叫 show 方法
      show(new Dog());  // 以 Dog 物件呼叫 show 方法
                
      Animal a = new Cat();  // 向上轉型  
      a.eat();               // 呼叫的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下轉型  
      c.work();        // 呼叫的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 型別判斷
        if (a instanceof Cat)  {  // 貓做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃魚");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨頭");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}
吃魚
抓老鼠
吃骨頭
看家
吃魚
抓老鼠

二、虛擬函式

1、Java中其實沒有虛擬函式的概念,它的普通函式就相當於C++的虛擬函式,動態繫結是Java的預設行為。如果Java中不希望某個函式具有虛擬函式特性,可以加上final關鍵字變成非虛擬函式。
2、在C++中,虛擬函式是在某基類中宣告為virtual並在一個或多個派生類中被重新定義的成員函式。
3、指向基類的指標在操作它的多型類物件時,會根據不同的類物件,呼叫其相應的函式,這個函式就是虛擬函式。
4、例項

class A{
    public void FUN(){
        System.out.println("FUN in A is called");
    }
}
class B extends A{
    public void FUN(){
        System.out.println("FUN in B is called");
    }
}
public class VirtualTest {

    public static void main(String args[])  {
        A a = new A();
        B b = new B();
        A p;

        p = a;
        p.FUN();
        p = b;
        p.FUN();
    }
}
FUN in A is called
FUN in B is called

重寫(Override)與過載(Overload)

一、重寫(Override)

1、子類定義了一個與其父類中具有相同名稱、引數列表和返回型別的方法,並且子類方法的實現覆蓋了父類方法的實現。即外殼不變,核心重寫。
2、子類可以根據需要,定義特定於自己的行為。也就是說子類能夠根據需要實現父類的方法。這樣在使用子類物件呼叫該方法時,將執行子類中的方法而不是父類中的方法。
3、重寫方法不能丟擲新的檢查異常或者比被重寫方法申明更加寬泛的異常。
4、例項

package com.example.helloworld;

class Animal1{
    public void move(){
        System.out.println("動物可以移動");
    }
}

class Dog1 extends Animal1{
    public void move(){
        System.out.println("狗可以跑和走");
    }
}

public class override_testdog{
    public static void main(String args[]){
        Animal1 a = new Animal1(); // Animal 物件
        Animal1 b = new Dog1(); // Dog 物件

        a.move();// 執行 Animal 類的方法

        b.move();//執行 Dog 類的方法
    }
}
動物可以移動
狗可以跑和走

5、方法的重寫規則

  • 引數列表與被重寫方法的引數列表必須完全相同。
  • 返回型別與被重寫方法的返回型別可以不相同,但是必須是父類返回值的派生類。
  • 訪問許可權不能比父類中被重寫的方法的訪問許可權更低。例如:如果父類的一個方法被宣告為public,那麼在子類中重寫該方法就不能宣告為protected。
  • 父類的成員方法只能被它的子類重寫。
  • 宣告為final的方法不能被重寫。
  • 宣告為static的方法不能被重寫,但是能夠被再次宣告。
  • 子類和父類在同一個包中,那麼子類可以重寫父類所有方法,除了宣告為private和final的方法。
  • 子類和父類不在同一個包中,那麼子類只能夠重寫父類的宣告為public和protected的非final方法。
  • 重寫的方法能夠丟擲任何非強制異常,無論被重寫的方法是否丟擲異常。但是,重寫的方法不能丟擲新的強制性異常,或者比被重寫方法宣告的更廣泛的強制性異常,反之則可以。
  • 構造方法不能被重寫。
  • 如果不能繼承一個類,則不能重寫該類的方法。

6、Super關鍵字的使用
當需要在子類中呼叫父類的被重寫方法時,要使用super關鍵字

class Animal{
   public void move(){
      System.out.println("動物可以移動");
   }
}
 
class Dog extends Animal{
   public void move(){
      super.move(); // 應用super類的方法
      System.out.println("狗可以跑和走");
   }
}
 
public class TestDog{
   public static void main(String args[]){
 
      Animal b = new Dog(); // Dog 物件
      b.move(); //執行 Dog類的方法
 
   }
}
動物可以移動
狗可以跑和走

二、過載(Overload)

1、過載(overloading)是在一個類裡面,方法名字相同,而引數不同。返回型別可以相同也可以不同。每個過載的方法(或者建構函式)都必須有一個獨一無二的引數型別列表。
2、過載規則:

  • 被過載的方法必須改變引數列表(引數個數或型別不一樣);
  • 被過載的方法可以改變返回型別;
  • 被過載的方法可以改變訪問修飾符;
  • 被過載的方法可以宣告新的或更廣的檢查異常;
  • 方法能夠在同一個類中或者在一個子類中被過載。
  • 無法以返回值型別作為過載函式的區分標準。

3、例項

package com.example.helloworld;

public class OverLoading {
    public int test(){
        System.out.println("test1");
        return 1;
    }

    public void test(int a){
        System.out.println("test2");
    }

    //以下兩個引數型別順序不同
    public String test(int a,String s){
        System.out.println("test3");
        return "returntest3";
    }

    public String test(String s,int a){
        System.out.println("test4");
        return "returntest4";
    }

    public static void main(String[] args){
        OverLoading o = new OverLoading();
        System.out.println(o.test());
        o.test(1);
        System.out.println(o.test(1,"test3"));
        System.out.println(o.test("test4",1));
    }
}
test1
1
test2
test3
returntest3
test4
returntest4

三、重寫與過載的區別

區別點 過載方法 重寫方法
引數列表 必須修改 一定不能修改
返回型別 可以修改 一定不能修改
異常 可以修改 可以減少或刪除,一定不能丟擲新的或者更廣的異常
訪問 可以修改 一定不能做更嚴格的限制(可以降低限制)

抽象類

一、概念

  • 如果一個類中沒有包含足夠的資訊來描繪一個具體的物件,這樣的類就是抽象類。
  • 抽象類除了不能例項化物件之外,類的其它功能依然存在,成員變數、成員方法和構造方法的訪問方式和普通類一樣。
  • 由於抽象類不能例項化物件,所以抽象類必須被繼承,才能被使用。
  • 父類包含了子類集合的常見的方法,但是由於父類本身是抽象的,所以不能使用這些方法。
  • 一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。
  • 構造方法,類方法(用 static 修飾的方法)不能宣告為抽象方法。

二、繼承抽象類

/* 檔名 : Employee.java */
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}
/* 檔名 : Salary.java */
public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}
/* 檔名 : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
 
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
 
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}
Constructing an Employee
Constructing an Employee
Call mailCheck using  Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.

三、抽象方法

1、父類中包含一個特別的成員方法,該方法的具體實現由它的子類確定,那麼就在父類中宣告該方法為抽象方法。
2、Abstract關鍵字也可用來宣告抽象方法,抽象方法只包含一個方法名,而沒有方法體。
3、抽象方法沒有定義,方法名後面直接跟一個分好,而不是花括號。
4、宣告抽象方法會造成以下兩個結果:

  • 如果一個類包含抽象方法,那麼該類必須是抽象類
  • 任何子類必須重寫父類的抽象方法,或者宣告自身為抽象類

5、在上述例項中,如果Salary類繼承了Employee類,那麼它必須實現computePay()方法

/* 檔名 : Salary.java */
public class Salary extends Employee
{
   private double salary; // Annual salary
  
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
 
   //其餘程式碼
}

介面

一、概念

1、介面(英文:Interface),在JAVA程式語言中是一個抽象型別,是抽象方法的集合,介面通常以interface來宣告。一個類透過繼承介面的方式,從而來繼承介面的抽象方法。
2、介面不是類。類描述物件的屬性和方法,介面則包含類要實現的方法。
3、除非實現介面的類是抽象類,否則該類要定義介面中的所有方法。
4、介面無法被例項化,但是可以被實現。一個實現介面的類,必須實現介面內所描述的所有方法,否則就必須宣告為抽象類。
5、在Java中,介面型別可用來宣告一個變數,他們可以成為一個空指標,或是被繫結在一個以此介面實現的物件。
6、介面與類相似點:

  • 一個介面可以有多個方法。
  • 介面檔案儲存在.java結尾的檔案中,檔名使用介面名。
  • 介面的位元組碼檔案儲存在.class結尾的檔案中。
  • 介面相應的位元組碼檔案必須在與包名稱相匹配的目錄結構中。

7、介面與類的區別:

  • 介面不能用於例項化物件。
  • 介面沒有構造方法。
  • 介面中所有的方法必須是抽象方法,Java 8之後,介面中可以使用default關鍵字修飾的非抽象方法。
  • 介面不能包含成員變數,除了static和final變數。
  • 介面不是被類繼承了,而是要被類實現。
  • 介面支援多繼承。

8、介面特性

  • 介面中每一個方法也是隱式抽象的,介面中的方法會被隱式的指定為public abstract(只能是public abstract,其他修飾符都會報錯)。
  • 介面中可以含有變數,但是介面中的變數會被隱式的指定為public static final變數(並且只能是public,用private修飾會報編譯錯誤)。
  • 介面中的方法是不能在介面中實現的,只能由實現介面的類來實現介面中的方法。

9、抽象類和介面的區別

  • 抽象類中的方法可以有方法體,就是能實現方法的具體功能,但是介面中的方法不行。
  • 抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是public static final型別的。
  • 介面中不能含有靜態程式碼塊以及靜態方法(用 static 修飾的方法),而抽象類是可以有靜態程式碼塊和靜態方法。
  • 一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

二、介面的宣告

1、語法格式

[可見度] interface 介面名稱 [extends 其他的介面名] {
        // 宣告變數
        // 抽象方法
}
  • 介面是隱式抽象的,宣告介面時,不必使用abstract關鍵字
  • 介面中的方法也是隱式抽象的,宣告時同樣不需要abstract關鍵字
  • 介面中的方法都是公有的
    2、例項
/* 檔名 : Animal.java */
interface Animal {
   public void eat();
   public void travel();
}

三、介面的實現

類使用implements關鍵字實現介面。在類宣告中,Implements關鍵字放在class宣告後面。
...implements 介面名稱[, 其他介面名稱, 其他介面名稱..., ...] ...

package com.example.helloworld;

/* 檔名 : MammalInt.java */
interface  Animal2{
    public void eat();
    public void travel();
};
public class MammalInt implements Animal2{

    public void eat(){
        System.out.println("Mammal eats");
    }

    public void travel(){
        System.out.println("Mammal travels");
    }

    public int noOfLegs(){
        return 0;
    }

    public static void main(String args[]){
        MammalInt m = new MammalInt();
        m.eat();
        m.travel();
    }
}

Mammal eats
Mammal travels

重寫介面中宣告的方法時,需要注意以下規則:

  • 類在實現介面的方法時,不能丟擲強制性異常,只能在介面中,或者繼承介面的抽象類中丟擲該強制性異常。
  • 類在重寫方法時要保持一致的方法名,並且應該保持相同或者相相容的返回值型別。
  • 如果實現介面的類是抽象類,那麼就沒必要實現該介面的方法。

在實現介面的時候,也要注意一些規則:

  • 一個類可以同時實現多個介面。
  • 一個類只能繼承一個類,但是能實現多個介面。
  • 一個介面能繼承另一個介面,這和類之間的繼承比較相似。

四、介面的繼承

介面的繼承使用extends關鍵字,子介面繼承父介面的方法。

// 檔名: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}
 
// 檔名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}
 
// 檔名: Hockey.java
public interface Hockey extends Sports
{
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

Hockey介面自己宣告瞭四個方法,從Sports介面繼承了兩個方法,這樣,實現Hockey介面的類需要實現六個方法。相似的,實現Football介面的類需要實現五個方法,其中兩個來自於Sports介面。

五、介面的多繼承

類的多繼承是不合法的,但介面允許多繼承。
public interface Hockey extends Sports, Event

六、標記介面

標記介面是沒有任何方法和屬性的介面.它僅僅表明它的類屬於一個特定的型別,供其他程式碼來測試允許做一些事情。簡單來說就是給某個物件打個標記,使物件擁有某個或某些特權。
標記介面主要用於以下兩種目的:

  • 建立一個公共的父介面
  • 向一個類新增資料型別

列舉

一、概念

1、列舉是個特殊的類,一般表示一組常量,如一年的12個月份。
2、列舉類使用enum關鍵字來定義,各常量使用","來分割。

enum Color 
{ 
    RED, GREEN, BLUE; 
} 
  
public class Test 
{ 
    // 執行輸出結果
    public static void main(String[] args) 
    { 
        Color c1 = Color.RED; 
        System.out.println(c1); 
    } 
}

RED

二、內部類中使用列舉

列舉類也可以宣告在內部類中

public class Test 
{ 
    enum Color 
    { 
        RED, GREEN, BLUE; 
    } 
  
    // 執行輸出結果
    public static void main(String[] args) 
    { 
        Color c1 = Color.RED; 
        System.out.println(c1); 
    } 
}

RED
每個列舉都是透過Class在內部實現的,且所有的列舉值都是public static final的。

三、迭代列舉元素

使用for語句來迭代列舉元素

enum Color 
{ 
    RED, GREEN, BLUE; 
} 
public class MyClass { 
  public static void main(String[] args) { 
    for (Color myVar : Color.values()) {
      System.out.println(myVar);
    }
  } 
}
RED
GREEN
BLUE

四、在switch中使用列舉類

enum Color 
{ 
    RED, GREEN, BLUE; 
} 
public class MyClass {
  public static void main(String[] args) {
    Color myVar = Color.BLUE;

    switch(myVar) {
      case RED:
        System.out.println("紅色");
        break;
      case GREEN:
         System.out.println("綠色");
        break;
      case BLUE:
        System.out.println("藍色");
        break;
    }
  }
}

藍色

五、values(), ordinal() 和valueOf()方法

  • values()返回列舉類中所有的值。
  • ordinal()方法可以找到每個列舉常量的索引,就像陣列索引一樣。
  • valueOf()方法返回指定字串值的列舉常量。
enum Color 
{ 
    RED, GREEN, BLUE; 
} 
  
public class Test 
{ 
    public static void main(String[] args) 
    { 
        // 呼叫 values() 
        Color[] arr = Color.values(); 
  
        // 迭代列舉
        for (Color col : arr) 
        { 
            // 檢視索引
            System.out.println(col + " at index " + col.ordinal()); 
        } 
  
        // 使用 valueOf() 返回列舉常量,不存在的會報錯 IllegalArgumentException 
        System.out.println(Color.valueOf("RED")); 
        // System.out.println(Color.valueOf("WHITE")); 
    } 
}
RED at index 0
GREEN at index 1
BLUE at index 2
RED

六、列舉類成員

1、列舉跟普通類一樣可以用自己的變數、方法和建構函式,建構函式只能使用private訪問修飾符,所以外部無法呼叫。
2、列舉既可以包含具體方法,也可以包含抽象方法。如果列舉類具有抽象方法,則列舉類的每個例項都必須實現它。

enum Color_2
{
    RED, GREEN, BLUE;

    // 建構函式
    private Color_2()
    {
        System.out.println("Constructor called for : " + this.toString());
    }

    public void colorInfo()
    {
        System.out.println("Universal Color");
    }
}

public class ColorTest_2
{
    // 輸出
    public static void main(String[] args)
    {
        Color_2 c1 = Color_2.RED;
        System.out.println(c1);
        c1.colorInfo();
    }
}
Constructor called for : RED
Constructor called for : GREEN
Constructor called for : BLUE
RED
Universal Color

相關文章