熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

面向對象思想之 -- 限制對象屬性的訪問

2013-11-23 18:49:18  來源: Java核心技術 

  雖然Java只支持從一個父類繼承但它使用接口的方式支持多重繼承
  接口實現了多態使得我們能夠給與對象不同特性以滿足不同的需要
  你可以使用多態機制讓完成相似功能的不同的方法擁有相同的名字但是擁有不同的參數列表
  動態/運行時的綁定機制允許一個對象在運行時被強制轉化成你所需要的對象類型前提是這個對象實現了必需的接口或者括展了特定的父類
  
  下面我們將討論通過限制對對象屬性和方法的訪問來強制實現對多重接口實現和父類拓展的正確使用的目的和實用性
  
  黑箱方法:封裝
  一個基本的面向對象的概念就是封裝將表示一個對象狀態的數據與其它對象隔離開來這一點是通過一個通常叫做作用域的概念來實現的作用域指的是編程語言的一種能力這種能力被用來實現一些限制對類或者結構體成員變量的訪問的規則大多數面向對象的語言支持作用域機制這些機制通常是通過諸如public protected 和 private之類的特殊關鍵字來實現的
  
  Java提供了四種不同的作用范圍:public package protected 和 private任何類方法或者成員變量都能通過使用public protected 和 private關鍵字來顯式的加以保護任何類方法或者成員變量如果沒有使用上面的關鍵字都將被隱式的給與package的作用范圍所有這些就構成了Java中命名空間的概念
  
  命名空間和軟件包
  一個命名空間可以被看成是在一個給定的上下文中一組相關的名字或是標識符命名空間避免了擁有相同名字或標識符的實體存在於同一個上下文裡這裡隱含的意思是只要實體是存在於不同的命名空間中那麼擁有相同名字或者標識符的實體就能夠呆在一塊兒Java使用軟件包的概念來實現命名空間和作用范圍控制
  
  軟件包是一個在統一的名字下的類和接口的集合每一個類或者接口都必須存在於用package關鍵字構成的軟件包申明語句定義的命名空間中例如下面的申明語句:
  
  package commycompanyappsHelloWorld;
  
  它申明了一個存在於commycompanyapps軟件包中的名叫HelloWorld的類或者接口軟件包申明總是放在包含了類或者接口定義的文件的頂部
  
  在java開發界目前對軟件包的命名有一個建議就是使用公司或組織的域名(以相反的順序)作為你的軟件包的第一部分因為域名是全球唯一的所以使用你的域名來命名你的軟件包也能使你軟件包的名字全球唯一
  
  如果一個Java類或者接口沒有包含一個軟件包申明那麼它就屬於unamed package也就是沒有名字的軟件包無名的軟件包應該只用來測試程序或是代碼原型等等
  
  請盡量使用封裝機制
  在任何程序風格中尤其是在面向對象的編程中將暴露的編程界面背後的實現細節隱藏起來是非常關鍵的這使得低層的實現方法能夠在不影響編程界面現有的客戶端的前提下改變而且能使對象完全自主的管理它們自己的狀態
  
  分離界面和實現方法的第一步就是隱藏類的內部數據要使一個成員變量或是方法對Java中所有潛在的客戶不可見可以將用private關鍵字將它聲明為私有成員變量如下所示:
  
  private int customerCount;
  
  要使一個成員變量或是方法除了其本身所屬類的子類以外對Java中所有潛在的客戶不可見可以使用protected關鍵字將它聲明成保護類型的如下所示:
  
  protected int customerCount;
  
  要使一個成員變量或是方法除了其本身所屬的類以外對Java中所有潛在的客戶不可見不使用任何關鍵字來聲明它如下所示:
  
  int customerCount;
  
  要將一個成員變量或是方法暴露給其所屬類的所有客戶可以用public關鍵字將它聲明為公共的成員變量如下所示:
  
  public int customerCount;
  
  訪問成員變量
  不論一個對象的數據隱藏得多麼好客戶仍然需要訪問一些隱藏的數據這是通過調用函數或方法來實現的在Java中使用特殊的被稱做屬性訪問器的方法來訪問隱藏的數據是可能的在Java中屬性訪問器和通常的函數之間並沒有本質的區別將一個通常的方法轉變成一個屬性訪問器唯一要做的事情就是參照一個命名規則來添加方法
  
  讀數據的訪問器的命名規則就是將方法命名為和數據域一樣的名字將首字母大寫然後在方法名字的前面添加get或是is數據訪問器的命名規則就是將方法命名為和數據域一樣的名字將首字母大寫然後在方法名字的前面添加set下面的例子演示了寫和讀數據的數據訪問器方法
  
  這是一個數據訪問器方法:
  
  public int getCustomerCount()
  {
    return(customerCount);
  }
  
  這是另一個數據訪問器方法
  
  public int isCustomerActive()
  {
    return(customerActive);
  }
  這是一個數據訪問器方法:
  
  public void setCustomerCount(int newValue)
  {
    customerCount = newValue;
  }
  使用訪問器方法允許其它對象訪問一個對象的隱藏數據而不直接涉及數據域這就允許擁有隱含數據的對象在改變成員變量以前做正確性檢查並控制成員變量是否應該被設置成新的值
  
  現在讓我們修改例子程序來使用這些概念如下所示
  
  public class HelloWorld
  {
    public static void main(String[] args)
    {
      Dog animal = new Dog();
      Cat animal = new Cat();
      Duck animal = new Duck();
      animalsetMood(AnimalCOMFORTED);
      Systemoutprintln(A comforted dog says +animalgetHello());
      animalsetMood(AnimalSCARED);
      Systemoutprintln(A scared dog says +animalgetHello());
      Systemoutprintln(Is a dog carnivorous? +animalisCarnivorous());
      Systemoutprintln(Is a dog a mammal? +animalisCarnivorous());
      animalsetMood(AnimalCOMFORTED);
      Systemoutprintln(A comforted cat says +animalgetHello());
      animalsetMood(AnimalSCARED);
      Systemoutprintln(A scared cat says +animalgetHello());
      Systemoutprintln(Is a cat carnivorous? +animalisCarnivorous());
      Systemoutprintln(Is a cat a mammal? +animalisCarnivorous());
      animalsetMood(AnimalCOMFORTED);
      Systemoutprintln(A comforted duck says +animalgetHello());
      animalsetMood(AnimalSCARED);
      Systemoutprintln(A scared duck says +animalgetHello());
      Systemoutprintln(Is a duck carnivorous? +animalisCarnivorous());
      Systemoutprintln(Is a duck a mammal? +animalisCarnivorous());
    }
  }
  
  abstract class Animal
  {
    // The two following fields are declared as public because they need to be
    // accessed by all clients
    public static final int SCARED = ;
    public static final int COMFORTED = ;
    // The following fields are declared as protected because they need to be
    // accessed only by descendant classes
    protected boolean mammal = false;
    protected boolean carnivorous = false;
    protected int mood = COMFORTED ;
    public boolean isMammal()
    {
      return(mammal);
    }
  
    public boolean isCarnivorous()
    {
      return(carnivorous);
    }
  
    abstract public String getHello();
  
    public void setMood(int newValue)
    {
      mood = newValue;
    }
  
    public int getMood()
    {
      return(mood);
    }
  }
  
  interface LandAnimal
  {
    public int getNumberOfLegs();
    public boolean getTailFlag();
  }
  
  interface WaterAnimal
  {
    public boolean getGillFlag();
    public boolean getLaysEggs();
  }
  
  class Dog extends Animal implements LandAnimal
  {
    // The following fields are declared private because they do not need to be
    // access by any other classes besides this one
    private int numberOfLegs = ;
    private boolean tailFlag = true;
    // Default constructor to make sure our properties are set correctly
    public Dog()
    {
      mammal = true;
      carnivorous = true;
    }
    // methods that override superclasss implementation
    public String getHello()
    {
      switch (mood) {
        case SCARED:
          return(Growl);
        case COMFORTED:
          return
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25793.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.