国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java核心技術(shù)筆記 對(duì)象與類

imtianx / 509人閱讀

摘要:核心技術(shù)卷第章對(duì)象與類面向?qū)ο蟪绦蛟O(shè)計(jì)創(chuàng)建標(biāo)準(zhǔn)類庫中的類對(duì)象如何編寫自己的類傳統(tǒng)的結(jié)構(gòu)化程序設(shè)計(jì)首先確定如何操作數(shù)據(jù),再?zèng)Q定如何組織數(shù)據(jù)。當(dāng)使用構(gòu)造器時(shí),無法改變所構(gòu)造的對(duì)象類型。

《Java核心技術(shù) 卷Ⅰ》 第4章 對(duì)象與類

面向?qū)ο蟪绦蛟O(shè)計(jì)

創(chuàng)建標(biāo)準(zhǔn)Java類庫中的類對(duì)象

如何編寫自己的類

OOP

傳統(tǒng)的結(jié)構(gòu)化程序設(shè)計(jì):首先確定如何操作數(shù)據(jù),再?zèng)Q定如何組織數(shù)據(jù)。

面向?qū)ο蟪绦蛟O(shè)計(jì):將數(shù)據(jù)放在第一位,再考慮操作數(shù)據(jù)的算法。

類(class)是構(gòu)造對(duì)象的模板或藍(lán)圖,  
由類構(gòu)造(construct)對(duì)象的過程稱為創(chuàng)建類的實(shí)例(instance)。

封裝(encapsulation),也稱數(shù)據(jù)隱藏,封裝將數(shù)據(jù)和行為組合在一個(gè)包中,并對(duì)對(duì)象使用者隱藏?cái)?shù)據(jù)實(shí)現(xiàn)方式,對(duì)象中的數(shù)據(jù)域稱為實(shí)例域(instance field),操作數(shù)據(jù)的過程稱為方法(method)。

對(duì)于每個(gè)特定的類實(shí)例(對(duì)象)都有一組特定的實(shí)例域值,這些值的集合就是這個(gè)對(duì)象的當(dāng)前狀態(tài)(state),只要向?qū)ο蟀l(fā)送一個(gè)消息,它的狀態(tài)就有可能發(fā)生改變。

實(shí)現(xiàn)封裝的關(guān)鍵:絕對(duì)不能讓類中的方法直接地訪問其他類的實(shí)例域。

OOP的另一個(gè)原則:可以通過擴(kuò)展一個(gè)類來建立另外一個(gè)新的類。在Java中,所有類都源于一個(gè)超類——Object

在擴(kuò)展一個(gè)已有類時(shí),新類具有這個(gè)類的全部屬性和方法,在新類中,只需要提供適用于這個(gè)新類的新方法和數(shù)據(jù)域就可以了,這個(gè)過程稱為繼承(inheritance)。

對(duì)象

對(duì)象的三個(gè)主要特性:

行為:可以讓對(duì)象做什么?

狀態(tài):被使用時(shí),如何響應(yīng)對(duì)應(yīng)的行為?

標(biāo)示:如何辨別具有相同行為與狀態(tài)的不同對(duì)象?

識(shí)別類

識(shí)別類的簡單規(guī)則:

使用的名詞:類

使用的動(dòng)詞:類的方法

類之間的關(guān)系

常見的關(guān)系有:

依賴(use-a):如果一個(gè)類的方法操縱另一個(gè)類的對(duì)象,我們說一個(gè)類依賴另一個(gè)類(即沒有這個(gè)類就無法完成指定的方法),比如消費(fèi)者想要支付,TA需要操作手機(jī)去完成具體的支付方式,即Customer "use-a" MobilePhone

聚合(has-a):聚合關(guān)系意味著類A的對(duì)象包含B的對(duì)象,比如程序員要喝咖啡,TA有一個(gè)杯咖啡,即Programmer "has-a" Coffee

繼承(is-a):類A擴(kuò)展類B,要做學(xué)生,先要做人,即Student "is-a" Person.

使用預(yù)定義類 對(duì)象與對(duì)象變量
想要使用對(duì)象,就必須首先構(gòu)造對(duì)象,并指定其初始狀態(tài),
然后對(duì)對(duì)象應(yīng)用方法。

在Java中,使用構(gòu)造器(constructor)構(gòu)造新實(shí)例,它是一種特殊的方法,用于構(gòu)造并初始化對(duì)象。

Date birthday = new Date();
String s = birthday.toString();

對(duì)象變量并沒有實(shí)際包含一個(gè)對(duì)象,而僅僅是一種引用,在Java中,任何對(duì)象變量的值都是對(duì)存儲(chǔ)在另外一個(gè)地方的一個(gè)對(duì)象的引用,new操作符的返回值也是一個(gè)引用。

當(dāng)一個(gè)對(duì)象變量只是聲明但是沒有具體的引用對(duì)象時(shí),調(diào)用其方法會(huì)在編譯時(shí)產(chǎn)生變量未初始化錯(cuò)誤。

// Error test P1
Date deadline;
deadline.toString();

當(dāng)一個(gè)對(duì)象變量只是聲明但是沒有具體的引用對(duì)象時(shí),調(diào)用其方法會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤(通常為java.lang.NullPointerException)。

// Error test P2
Date deadline = null;
deadline.toString();

上面兩個(gè)例子說明,Java中的局部變量并不會(huì)自動(dòng)地初始化為null,而必須通過調(diào)用new或?qū)⑺麄冊(cè)O(shè)置為null進(jìn)行初始化。

LocalDate類
Date類的實(shí)例有一個(gè)狀態(tài),即特定的時(shí)間點(diǎn)。

時(shí)間是距離紀(jì)元(epoch)的毫秒數(shù)(可正可負(fù)),紀(jì)元是UTC(Coordinated Universal Time)時(shí)間1970年1月1日 00:00:00。

類庫設(shè)計(jì)者把保存時(shí)間給時(shí)間點(diǎn)命名分開,所以標(biāo)準(zhǔn)Java類庫分別包含了兩個(gè)類:

表示時(shí)間點(diǎn)的Date

日歷表示法的LocalDate

不要使用構(gòu)造器來構(gòu)造LocalDate類的對(duì)象,應(yīng)用靜態(tài)工廠方法(factory method)代表調(diào)用構(gòu)造器。

// 當(dāng)前時(shí)間的對(duì)象
LocalDate.now();
// 指定時(shí)間的對(duì)象
LocalDate.of(1996, 6, 30);
// 保存對(duì)象
LocalDate birthday = LocalDate.of(1996, 6, 30);

有了對(duì)象就可以使用方法獲得年、月、日。

int year = birthday.getYear(); // 1996
int month = birthday.getMonthValue(); // 6
int day = birthday.getDayOfMonth(); // 30
int dayOfWeek = birthday.getDayOfWeek().getValue(); // 7

需要計(jì)算某個(gè)日期時(shí):

LocalDate someday = birthday.plusDays(708);
int year = someday.getYear(); // 1998
int month = someday.getMonthValue(); // 6
int day = someday.getDayOfMonth(); // 8
// 當(dāng)然還有minusDays方法
更改器方法與訪問器方法

更改器方法(mutator method):調(diào)用后,對(duì)象的狀態(tài)會(huì)改變。

訪問器方法(accessor method):只訪問對(duì)象而不修改對(duì)象狀態(tài)的方法。

用戶自定義類 簡單類定義

Java簡單類的形式:

class ClassName
{
  filed1
  field2
  ...
  constructor1
  constructor2
  ...
  method1
  method2
  ...
}

一個(gè)使用簡單類的程序例子:

// File EmployeeTest.java
public class EmployeeTest
{
  public static void main(String[] args)
  {
    Employee[] staff = new Employee[3];
    staff[0] = new Employee("Bob Hacker", 75000, 1996, 6, 30);
    ...
  }
}

class Employee
{
  // instance fields
  private String name;
  private double salary;
  private LocalDate hireDay;

  // constructor
  public Employee(String n, double s, int year, int month, int day)
  {
    name = n;
    salary = s;
    hireDay = LocalDate.of(year, month, day);
  }

  // methods
  public String getName()
  {
    return name;
  }

  ...
}

注意,這個(gè)程序中包含兩個(gè)類:

Employee

帶有public訪問修飾符的EmployeeTest

源文件名是EmployeeTest.java,這是因?yàn)槲募?strong>必須與public類的名字相匹配,在一個(gè)源文件中,只能有一個(gè)公有類,但可以有任意個(gè)非公有類。

當(dāng)編譯這段源碼時(shí),編譯器會(huì)在目錄下生成兩個(gè)類文件:EmployeeTest.classEmployee.class

將程序中包含main方法的類名提供給字節(jié)碼解釋器,啟動(dòng)程序:

java EmployeeTest

字節(jié)碼解釋器開始運(yùn)行其中的main方法的代碼。

構(gòu)造器

剛才所使用類中的構(gòu)造器:

class Employee
{
  ...
  public Employee(String n, double s, int year, int month, int day)
  {
    name = n;
    salary = s;
    hireDay = LocalDate.of(year, month, day);
  }
  ...
}

構(gòu)造器與類同名,在構(gòu)造Employee類對(duì)象時(shí),對(duì)應(yīng)的構(gòu)造器會(huì)運(yùn)行,執(zhí)行代碼將實(shí)例域初始化所指定的狀態(tài)。

構(gòu)造器與方法的其中一個(gè)不同是,構(gòu)造器總是伴隨new操作符的執(zhí)行被調(diào)用,并且不能對(duì)已經(jīng)存在的對(duì)象調(diào)用構(gòu)造器來重新設(shè)置實(shí)例域。

Employee bob = new Employee("Bob", 47000, ...);
bob.Employee("Bob", 47500, ...);
// Compiler Error: Can"t find symbol of method Person(String, int, ...)

構(gòu)造器基礎(chǔ)的簡單總結(jié):

構(gòu)造器與類同名

構(gòu)造器可以有任意個(gè)參數(shù),甚至沒有參數(shù)

構(gòu)造器沒有返回值

構(gòu)造器伴隨new操作一起調(diào)用

每個(gè)類可以有一個(gè)以上的構(gòu)造器

多個(gè)構(gòu)造器時(shí),根據(jù)調(diào)用new的參數(shù)類型來進(jìn)行選擇

隱式參數(shù)與顯式參數(shù)
方法用于操作對(duì)象以及存取他們的示例域。
public void raiseSalary(double byPercent)
{
  double raise = salary * byPercent / 100;
  salary += raise;
}

當(dāng)對(duì)象調(diào)用方法時(shí)

bob.raiseSalary(5);

raiseSalary方法有兩個(gè)參數(shù)。

隱式(implicit)參數(shù),這里指的是現(xiàn)在方法名前的Employee類的對(duì)象。

顯示(explicit)參數(shù),這里指的是位于方法名后括號(hào)中的數(shù)據(jù)。

在每一個(gè)方法中,關(guān)鍵字this表示隱式參數(shù),上面的方法也可以寫為:

public void raiseSalary(double byPercent)
{
  // double raise = salary * byPercent / 100;
  double raise = this.salary * byPercent / 100;
  // salary += raise;
  this.salary += raise;
}

有些人偏愛這樣寫(包括我),雖然費(fèi)事點(diǎn),但是可以將實(shí)例域與局部變量明顯的區(qū)分開來。

封裝的優(yōu)點(diǎn)

封裝對(duì)于直接簡單的公有數(shù)據(jù)而言,提供了更多對(duì)公有數(shù)據(jù)保護(hù)的途徑。

對(duì)于訪問器來說,它們只返回實(shí)例域的值,并且在處理可引用的返回對(duì)象時(shí),要通過clone來創(chuàng)建新的對(duì)象來作為返回值的載體,如果將可引用對(duì)象直接返回,并且該對(duì)象恰有一個(gè)可修改值的方法時(shí),任何外部對(duì)這個(gè)返回值的處理都將會(huì)直接影響到這個(gè)對(duì)象內(nèi)部的對(duì)象(Java引用在這部分的情況類似與C中的指針)。

對(duì)于更改器來說,它們?cè)诒徽{(diào)用時(shí)可以主動(dòng)的執(zhí)行數(shù)據(jù)合法性的檢查,從而避免破壞數(shù)據(jù)的合法性。

基于類的訪問權(quán)限

方法可以訪問所調(diào)用對(duì)象的私有數(shù)據(jù)。

但是Java其實(shí)還要更進(jìn)一步:一個(gè)方法可以訪問所屬類所有對(duì)象私有數(shù)據(jù)

// class
class Employee
{
  public boolean equals(Employee other) {
    return name.equals(other.name);
  }
}
...
// main
if(harry.equals(boss)) ...

這個(gè)方法訪問harry的私有域,同時(shí)它還訪問了boss的私有域,這是合法的,boss也是Employee類對(duì)象,Employee類的方法可以訪問Employee類的任何一個(gè)對(duì)象的私有域。

私有方法

有時(shí)候?yàn)榱送瓿扇蝿?wù)需要寫一些輔助方法,這些輔助方法不應(yīng)該稱為公有接口的一部分,這是由于它們與當(dāng)前的實(shí)現(xiàn)機(jī)制非常緊密,最好將這樣的方法設(shè)計(jì)為private

簡單來說,為了更好地封裝性,不在公有接口范圍內(nèi)的方法都應(yīng)該設(shè)計(jì)為private

final實(shí)例域

類中可以定義實(shí)例域?yàn)?b>final,但是必須確保在每一個(gè)構(gòu)造器執(zhí)行之后,這個(gè)域的值會(huì)被設(shè)置,并在后面的操作中不能再對(duì)其進(jìn)行修改。

但是這里的不能修改大都應(yīng)用于基本(primitive)類型和不可變(immutable)類型的域(如果類中每個(gè)方法都不會(huì)改變對(duì)象狀態(tài),則類就是不可變的類,例如String類)。

對(duì)于可變的類(比如之前的StringBuilder類),使用final修飾符只是表示該變量的對(duì)象引用不會(huì)再指示其他的對(duì)象,但其對(duì)象本身是可以更改的(比如StringBuilder類的對(duì)象執(zhí)行append方法)。

靜態(tài)域與靜態(tài)方法 靜態(tài)域
如果將一個(gè)域定義為static,每個(gè)類中只有這樣的一個(gè)域。

通俗來講,如果一個(gè)域被定義為static,那么這個(gè)域?qū)儆谶@個(gè)類,而不屬于任何這個(gè)類的對(duì)象,這些對(duì)象同時(shí)共享這個(gè)域(有點(diǎn)像類的一個(gè)全局變量域)。

一個(gè)簡單的靜態(tài)域用法:

// class Employee
...
// 可以在類定義中直接對(duì)靜態(tài)域賦予一個(gè)初值。
private static int nextId = 1;
private int id;
...
public void setId()
{
  id = nextId;
  nextId++;
}
靜態(tài)常量

靜態(tài)常量相比于靜態(tài)變量使用的要多一些。

例如Math類中的PI

public class Math
{
  ...
  publuc static final double PI =  3.14159265358979323846;
  ...
}

程序通過Math.PI的形式獲得這個(gè)常量。

靜態(tài)方法
靜態(tài)方法是一種不能向?qū)ο髮?shí)施操作的方法。

靜態(tài)方法在調(diào)用時(shí),不使用任何實(shí)例對(duì)象,換句話說就是沒有隱式參數(shù)。

需要使用靜態(tài)方法的情況:

一個(gè)方法不需要訪問對(duì)象狀態(tài),參數(shù)都是顯示參數(shù)提供

一個(gè)方法只需要訪問類的靜態(tài)域

工廠方法

比如之前LocalDate類使用的靜態(tài)工廠方法(factory method)來構(gòu)造對(duì)象。

不利用構(gòu)造器完成這個(gè)操作的兩個(gè)原因:

無法命名構(gòu)造器。構(gòu)造器的名字必須與類名相同。

當(dāng)使用構(gòu)造器時(shí),無法改變所構(gòu)造的對(duì)象類型。

main方法

main方法不對(duì)任何對(duì)象進(jìn)行操作,因?yàn)槭聦?shí)上在啟動(dòng)程序時(shí)還沒有任何一個(gè)對(duì)象,靜態(tài)的main方法將隨著執(zhí)行創(chuàng)建程序所需要的對(duì)象。

同時(shí),每一個(gè)類都可以有一個(gè)main方法,常用于進(jìn)行類的單元測(cè)試。

方法參數(shù)

在程序設(shè)計(jì)語言中有關(guān)參數(shù)傳遞給方法(函數(shù))的一些專業(yè)術(shù)語:

按值調(diào)用(call by value):表示方法接收的是調(diào)用者提供的值。

按引用調(diào)用(call by reference):標(biāo)識(shí)方法接收的是調(diào)用者提供的變量地址。

Java程序設(shè)計(jì)語言總是采用按值調(diào)用,即方法得到的只是參數(shù)值的一個(gè)拷貝,不能修改傳遞給它的任何參數(shù)變量的內(nèi)容。

但是當(dāng)對(duì)象引用作為參數(shù)時(shí),情況就不同了,方法獲得的是對(duì)象引用的拷貝,對(duì)象引用和其他拷貝同時(shí)引用同一個(gè)對(duì)象。

但是這并不是引用調(diào)用。

public static void swap(Obejct a, Obejct b)
{
  Object tmp = a;
  a = b;
  b = tmp;
}

如果Java在對(duì)象參數(shù)時(shí)采用的是按引用調(diào)用,上述方法就能實(shí)現(xiàn)交換數(shù)據(jù)的效果。

但是這里的swap方法并沒有改變存儲(chǔ)在調(diào)用參數(shù)中的對(duì)象引用,swap方法的參數(shù)ab被初始化為兩個(gè)對(duì)象引用的拷貝,這個(gè)方法交換的是這兩個(gè)拷貝的引用。

Java中方法參數(shù)總結(jié):

方法不能修改基本數(shù)據(jù)類型的參數(shù)

方法可以改變對(duì)象參數(shù)的狀態(tài)

方法不能讓對(duì)象參數(shù)引用一個(gè)新的對(duì)象

對(duì)象構(gòu)造 重載
有些類有多個(gè)多個(gè)構(gòu)造器。

這種特征叫做重載(overloading),如果多個(gè)方法有相同的名字、不同的參數(shù),便產(chǎn)生了重載。

編譯器通過用各個(gè)方法給出的參數(shù)類型與特定方法調(diào)用所使用的值類型進(jìn)行匹配來挑選出相應(yīng)的方法,如果編譯器找不到匹配的參數(shù),就會(huì)產(chǎn)生編譯時(shí)錯(cuò)誤。

Java允許重載任何方法,并不只是構(gòu)造器,因此要完整地描述一個(gè)方法,需要指出方法名以及參數(shù)類型,這叫方法的簽名(signature)。

// 方法重載的簽名舉例
indexOf(int)
indexOf(int int)
indexOf(String)

可以看出,返回類型并不是方法簽名的一部分,即不能有兩個(gè)名字相同、參數(shù)類型相同但是卻返回不同類型值的方法。

默認(rèn)域初始化

如果域沒有在構(gòu)造器中被賦予初值,則會(huì)被自動(dòng)地賦予默認(rèn)值

數(shù)值:0

布爾:false

對(duì)象引用:null

這與局部變量的聲明不同,局部變量必須明確的進(jìn)行初始化。

構(gòu)造器中如果不明確地進(jìn)行初始化,會(huì)影響代碼的可讀性。

無參數(shù)的構(gòu)造器

如果在編寫一個(gè)類時(shí)沒有編寫構(gòu)造器,那么系統(tǒng)會(huì)提供一個(gè)無參數(shù)構(gòu)造器,這個(gè)構(gòu)造器將所有的實(shí)例域設(shè)置為默認(rèn)值。

如果類中提供了至少一個(gè)構(gòu)造器,但是沒有提供無參數(shù)構(gòu)造器,則構(gòu)造對(duì)象時(shí)如果沒有提供參數(shù)就會(huì)被視為不合法。

顯式域初始化

通過重載類的構(gòu)造器方法,可以采用多種形式設(shè)置類的實(shí)例域的初始狀態(tài)。

可以在類定義中,直接講一個(gè)值賦予給任何域。

class Employee
{
  private String name = "";
  ...
}

在構(gòu)造器執(zhí)行之前,先執(zhí)行賦值操作。

初始值也可以不用是常量。

class Employee
{
  private static int nextId;
  private int id = assignId();
  ...
  private static int assignId()
  {
    int r = nextId;
    nextId++;
    return r;
  }
  ...
}

上面的例子中,可以調(diào)用方法對(duì)域進(jìn)行初始化。

參數(shù)名

在編寫很小的構(gòu)造器時(shí),通常用單個(gè)字符命名:

public Employee(String n, double s)
{
  name = n;
  salary = s;
}

這樣的缺陷是失去了代碼可讀性,也可以采用加前綴的方法:

public Employee(String aName, double aSalary)
{
  name = aName;
  salary = aSalary;
}

當(dāng)然還有一種技巧,參數(shù)變量用同樣的名字將實(shí)例域屏蔽起來:

public Employee(String name, double salary)
{
  this.name = name;
  this.salary = salary;
}
調(diào)用另一個(gè)構(gòu)造器

如果構(gòu)造器的第一個(gè)語句形如this(...),這個(gè)構(gòu)造器將調(diào)用同一個(gè)類的另一個(gè)構(gòu)造器。

public Employee(double s)
{
  // calls Employee(String, double)
  this("Employee #" + nextId, s);
  nextId++;
}
初始化塊

除了前面提到的兩種初始化數(shù)據(jù)域的方法:

在構(gòu)造器中設(shè)置值

在聲明中賦值

還有第三種,稱為初始化塊(initialization block),在類定義中可以包含多個(gè)代碼塊,只要構(gòu)造類的對(duì)象,這些塊就會(huì)被執(zhí)行。

class Employee
{
  private static int nextId = 0;
  private int id;

  {
    id = nextId;
    nextId++;
  }
  ...
}

無論哪個(gè)構(gòu)造器構(gòu)造對(duì)象,初始化塊都會(huì)執(zhí)行,首先運(yùn)行初始化塊,然后才運(yùn)行構(gòu)造器的主體部分。

調(diào)用構(gòu)造器的具體處理步驟:

所有數(shù)據(jù)域被初始化為默認(rèn)值

按照出現(xiàn)次序執(zhí)行初始化語句和初始化塊

如果構(gòu)造器調(diào)用了第二個(gè)構(gòu)造器,則執(zhí)行第二個(gè)構(gòu)造器主體

執(zhí)行這個(gè)構(gòu)造器主體

初始化塊比較常用于代碼比較復(fù)雜的靜態(tài)域初始化:

static
{
  Random generator = new Random();
  nextId = generator.nextInt(10000);
}
Java允許使用包(package)將類組織起來。  
借助于包可以方便地組織自己的代碼,并將自己的代碼與別人提供的代碼庫分開管理。

標(biāo)準(zhǔn)的Java類庫分布在多個(gè)包中,包括java.langjava.utiljava.net等。

使用包的主要原因是確保類名的唯一性。

假如兩個(gè)程序員都建立了Employee類,只要將類放置在不同的包中,就不會(huì)產(chǎn)生沖突。

從編譯器角度來說,嵌套的包之間沒有任何關(guān)系。例如java.util包與java.util.jar包毫無關(guān)系。

類的導(dǎo)入

一個(gè)類可以使用所屬包的所有類,以及其他包中的公有類(public class)

可以使用兩種方式訪問另一個(gè)包中的公有類。

在類名前添加完整地包名

使用import語句,可以導(dǎo)入一個(gè)特定的類或者整個(gè)包。

// 添加包名
java.time.LocalDate today = java.time.LocalDate.now();

// import
import java.util.*;
// or import java.time.LocalDate 引入特定類
LocalDate today = LocalDate.now();

大多數(shù)情況下導(dǎo)入包即可,但是在發(fā)生命名沖突的時(shí)候,就要注意了,

import java.util.*;
import java.sql.*;

Date today; // Error

因?yàn)檫@兩個(gè)包都有Date類,編譯器無法確定是哪一個(gè)包的Date類,所以這個(gè)時(shí)候可以增加一個(gè)指定特定類的import語句。

如果兩個(gè)類都要使用時(shí),就在每個(gè)類名前加上完整地包名。

靜態(tài)導(dǎo)入

import語句還增加了導(dǎo)入靜態(tài)方法和靜態(tài)域的功能。

import static java.lang.System.*;
// 然后可以使用System類的靜態(tài)方法和靜態(tài)域而不必加前綴
out.println("Hohoho!");
// System.out.println()

另外,還可以導(dǎo)入特定的方法或域:

import stattic java.lang.System.out;
out.println("Hohoho!");
將類放入包中

想將一個(gè)類放入包中,就必須將包的名字放在源文件的開頭。

package com.horstmann.corejava;

public clas Employee
{
  ...
}

如果沒有在源文件中放置package語句,源文件中的類被放置在默認(rèn)包(default package)中,默認(rèn)包是一個(gè)沒有名字的包。

一般需要把包中的文件放到與完整的包名匹配的子目錄中。

例如package com.horstmann.corejava包中的所有源文件,應(yīng)該被放置在子目錄com/horstmann/corejava中。

包作用域

標(biāo)記為public的類、方法、變量可以被任意的類使用

標(biāo)記為private的類、方法、變量只能被定義他們的類使用

如果沒有指定,則他們可以被同一個(gè)包中的所有方法訪問

文檔注釋

JDK包含一個(gè)很用有的工具——javadoc,它可以由源文件生成一個(gè)HTML文檔。

在源代碼中添加以專用的定界符/**開始的注釋,則可以容易地生成形式上專業(yè)的文檔,相比于把文檔和代碼多帶帶存放,修改代碼的同時(shí)修改文檔注釋再重新運(yùn)行javadoc,就不會(huì)出現(xiàn)不一致的問題。

注釋的插入

javadoc從下面幾個(gè)特性中抽取信息:

公有類與接口

公有的和受保護(hù)的構(gòu)造器及方法

公有的和受保護(hù)的域

應(yīng)該為這幾部分編寫注釋,注釋應(yīng)該放在所描述特性的前面。

注釋以/**開始,以*/結(jié)束。

每個(gè)/**...*/文檔注釋中使用自由格式文本(free-form text),標(biāo)記由@開始。

類注釋

類注釋必須放在import語句之后,類定義之前。

/**
 * Just some comment words here
 * another comment line
 * what is this class for?
 */
public class Card
{
  ...
}
方法注釋

方法注釋放在描述的方法前,除了通用標(biāo)記,還可以使用下面的標(biāo)記:

@param 變量 描述:用于標(biāo)記當(dāng)前方法的參數(shù)部分的一個(gè)條目

@return 描述:用于標(biāo)記方法的返回部分

@throws類 描述:表示方法有可能拋出異常

/**
 * Buy one coffee.
 * @param money the cost of coffee
 * @param coffeeTpye which coffee
 * @return coffee one hot coffee
 * @throws NoMoreCoffee
 */
public buyCoffee(double money, CoffeeType coffeeTpye)
{
  ...
}
域注釋

只需要對(duì)公有域(通常是靜態(tài)常量)建議文檔。

/**
 * The ratio of a circle"s circumference to its diameter
 */
public static final double PI = 3.1415926...;
通用注釋

可用在類文檔的注釋的標(biāo)記:

@author 姓名:可以使用多個(gè)

@version 文本:版本條目

@since 文本:始于...條目,這里的文本可以是對(duì)版本的描述

@deprecated 文本:標(biāo)記對(duì)類、方法或變量不再使用,例如:

@deprecated Use  setVisible(true)  instead

@see 引用:增加一個(gè)超鏈接,可以用于類、方法中,引用有以下情況:

package.class#feature label

// 建立一個(gè)連接到com.horstmann.corejava.Employee類的raiseSalary(double)方法的超鏈接
@see com.horstmann.corejava.Employee#raiseSalary(double)
// 可以省略包名,甚至把包名和類名省去
@see Employee#raiseSalary(double)
// 此時(shí)鏈接定位于當(dāng)前包
  @see raiseSalary(double)
// 此時(shí)連接定位于當(dāng)前類

label

@see The Core ]ava home page
// 此處可以使用label標(biāo)簽屬性來添加用戶看到的錨名稱

"text"

@see "Core Java 2 volume 2n"

如果愿意的話,還可以在注釋的任何位置放置指向其他類和方法的超鏈接:

{ @link package.class#feature label }
// 這里的描述規(guī)則與@see標(biāo)記規(guī)則一樣
包與概述注釋

如果想要包的注釋,就要在每一個(gè)包的目錄中添加一個(gè)多帶帶的文件。

提供一個(gè)以package.html命名的文件,在...之間的所有文本會(huì)被抽取。

提供一個(gè)以package-info.java命名的文件,這個(gè)文件包含一個(gè)初始的以/***/界定的Javadoc注釋,跟隨在一個(gè)包語句之后。

還可以為所有的源文件提供一個(gè)概述性的注釋,這個(gè)注釋將被放置在一個(gè)名為overview.html的文件中,這個(gè)文件位于包含所有源文件的父目錄中,標(biāo)記...之間的所有文本會(huì)被抽取。當(dāng)用戶選擇overview時(shí),就會(huì)查看到這些注釋內(nèi)容。

類設(shè)計(jì)技巧
應(yīng)用這些技巧可以設(shè)計(jì)出更具有OOP專業(yè)水準(zhǔn)的類。
一定要保證數(shù)據(jù)私有
絕對(duì)不要破壞封裝性,這是最重要的。

數(shù)據(jù)的表示形式很可能會(huì)改變,但是它們的使用方式卻不會(huì)經(jīng)常發(fā)生變化,當(dāng)數(shù)據(jù)保持私有時(shí),它們的表示形式的變化不會(huì)對(duì)類的使用者產(chǎn)生影響,即使出現(xiàn)bug也易于檢測(cè)。

一定要對(duì)數(shù)據(jù)初始化
Java不對(duì)局部變量進(jìn)行初始化,但是會(huì)對(duì)對(duì)象的實(shí)例域進(jìn)行初始化。

但是也最好不要依賴系統(tǒng)的默認(rèn)值,應(yīng)該用構(gòu)造器或者是提供默認(rèn)值的方式來顯式地初始化所有的數(shù)據(jù)。

不要在類中使用過多的基本類型
用其他的類代替多個(gè)相關(guān)的基本類型的使用。

這樣會(huì)使類更加易于理解和修改。

比如用一個(gè)Address的類來代替下面的實(shí)例域:

private String street;
private String city;
private String state;
private int zip;

這樣更容易理解和處理表示地址的域,而使用這些域的類并不用去關(guān)心這些域是怎么具體變化的。

不是所有的域都需要獨(dú)立的域訪問和更改器

有些域在對(duì)象被構(gòu)造出來后,在類的設(shè)計(jì)上,可能不再允許被修改

在對(duì)象中有時(shí)候包含一些不希望別人獲得或設(shè)置的實(shí)例域

將職責(zé)過多的類進(jìn)行分解

雖然這里的“過多”對(duì)于個(gè)人來說是一個(gè)含糊的概念,但是如果明顯地可以將一個(gè)復(fù)雜的類分解成兩個(gè)更為簡單的類,則應(yīng)該進(jìn)行分解。

類名和方法名要能體現(xiàn)職責(zé)

命名類名的良好習(xí)慣是采用:

名詞 Order

前面有形容詞修飾的名詞 RushOrder

動(dòng)名詞修飾的名詞 BillingAddress

對(duì)于方法來說:

訪問器用小寫的get開頭

更改起用小寫的set開頭

優(yōu)先使用不可變的類

更改對(duì)象的問題在于:如果多個(gè)線程視圖同時(shí)更新一個(gè)對(duì)象,就會(huì)發(fā)生并發(fā)更改,其結(jié)果是不可預(yù)料的。如果類時(shí)不可變的,就可以安全地在多個(gè)線程間共享其對(duì)象。

Java對(duì)象與類總結(jié)

OOP的簡要概念

類與對(duì)象

類之間的關(guān)系

對(duì)象與對(duì)象變量

更改器與訪問器

自定義類

構(gòu)造器

隱式參數(shù)與顯式參數(shù)

封裝

基于類的訪問權(quán)限

私有方法

final實(shí)例域

靜態(tài)域與靜態(tài)方法

按值調(diào)用

重載

默認(rèn)域的初始化

無參數(shù)構(gòu)造器

顯式域初始化

初始化塊

文檔注釋

類設(shè)計(jì)技巧

個(gè)人靜態(tài)博客:

氣泡的前端日記: https://rheabubbles.github.io

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/72917.html

相關(guān)文章

  • Spring IoC學(xué)習(xí)總結(jié)

    摘要:學(xué)習(xí)總結(jié)學(xué)習(xí)整理的一些筆記,很簡單。大部分認(rèn)為和只是不同的叫法而已。依賴注入的兩種方式和注解使用注釋驅(qū)動(dòng)的功能源碼剖析 Spring IoC學(xué)習(xí)總結(jié) 學(xué)習(xí)spring Ioc整理的一些筆記,很簡單。分享給大家。 IoC 基本概念 在這之前,我們先記住一句話。好萊塢原則:Dont call us, we will call you.其實(shí)這句話很恰當(dāng)?shù)匦稳萘朔崔D(zhuǎn)的意味;Ioc, Inve...

    silencezwm 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式》閱讀筆記_part2

    摘要:它屬于類創(chuàng)建型模式。基于繼承,將復(fù)雜的放置在函數(shù)中,簡單的共同的放置到一個(gè)構(gòu)造函數(shù)中。代碼與繼承類似,但是核心就是將簡單的共有的放置到構(gòu)造函數(shù)中,與類的思想類似。單例模式實(shí)現(xiàn)代碼庫,產(chǎn)生命名空間,一次只能實(shí)例化一個(gè)。 JavaScript設(shè)計(jì)模式閱讀 更多文章查看本專欄 設(shè)計(jì)模式第一篇:創(chuàng)建型設(shè)計(jì)模式 1、簡單工廠模式 簡單工廠模式:又叫靜態(tài)工廠方法,有一個(gè)工廠對(duì)象決定創(chuàng)建某一種產(chǎn)品...

    RobinTang 評(píng)論0 收藏0
  • 1、接口 2、多態(tài)

    摘要:接口的概念接口的概念接口是功能的集合,同樣可看做是一種數(shù)據(jù)類型,是比抽象類更為抽象的類。多態(tài)的前提是必須有子父類關(guān)系或者類實(shí)現(xiàn)接口關(guān)系,否則無法完成多態(tài)。 01接口的概念 * A:接口的概念 接口是功能的集合,同樣可看做是一種數(shù)據(jù)類型,是比抽象類更為抽象的類。 接口只描述所應(yīng)該具備的方法,并沒有具體實(shí)現(xiàn),具體的實(shí)現(xiàn)由接口的實(shí)現(xiàn)類(相當(dāng)于接口的子類)來完成。這樣將功能的定...

    Magicer 評(píng)論0 收藏0
  • 第3章:抽象數(shù)據(jù)類型(ADT)和面向對(duì)象編程(OOP) 3.4面向對(duì)象編程(OOP)

    摘要:抽象數(shù)據(jù)類型的多個(gè)不同表示可以共存于同一個(gè)程序中,作為實(shí)現(xiàn)接口的不同類。封裝和信息隱藏信息隱藏將精心設(shè)計(jì)的模塊與不好的模塊區(qū)分開來的唯一最重要的因素是其隱藏內(nèi)部數(shù)據(jù)和其他模塊的其他實(shí)施細(xì)節(jié)的程度。 大綱 面向?qū)ο蟮臉?biāo)準(zhǔn)基本概念:對(duì)象,類,屬性,方法和接口OOP的獨(dú)特功能 封裝和信息隱藏 繼承和重寫 多態(tài)性,子類型和重載 靜態(tài)與動(dòng)態(tài)分派 Java中一些重要的Object方法設(shè)計(jì)好的類面向...

    Heier 評(píng)論0 收藏0
  • <java核心技術(shù)>讀書筆記2

    摘要:如果需要收集參數(shù)化類型對(duì)象,只有使用警告這節(jié)討論,向參數(shù)可變的方法傳遞一個(gè)泛型類型的實(shí)例。異常不能拋出或捕獲泛型類的實(shí)例實(shí)際上,泛型類擴(kuò)展也是不合法的。 Object:所有類的超類 java中每個(gè)類都是由它擴(kuò)展而來,但是并不需要這樣寫:class Employee extends Object.如果沒有明確指出超類,Object類就被認(rèn)為是這個(gè)的超類。可以使用Object類型的變量引用...

    jimhs 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<