constructor
是一種Java中的構造器,也是class
的其中一個成員,透過new class();
的格式去進行創建
假設今天有一個class Person
和class PersonTest
在同一個package
中(還記得為什麼要在同一個package
中嗎?因為沒有加上public
在Person
前面,他的權限最多僅限於在同一個package
中使用)
程式碼如下:
class Person {
private String name;
int age;
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
}
public class PersonTest {
public static void main(String[] args) {
Person person = new Person();
person.age = 20;
person.setName("Jack");
System.out.println(person.getName()); // Jack
}
}
Person
class
,並且在裡面宣告了private
(私有,只能在Person
class
中使用)的name
屬性、和一個default
(未填寫,可以在相同的package
中使用)的 age
屬性,以及public
的setName
和getName
方法去獲取name
屬性的值。setName
帶有一個參數
n
並且將n
賦值給name
屬性getName
將Person
class
的私有
屬性name
返回,以提供給需要name
值的class
使用PersonTest
class
,並在裡面宣告了一個main
的入口點,裡面實例化
了一個Person
class
,並且透過person.age = 20;
,將20賦值給了age
,並且透過person.setName("Jack");
將Jack賦值給name
屬性person.getName();
將name
的值提供給System.out.println();
使用並列印在terminal
中由上述可以看到,當實例化
一個class
時,如果透過class.xxx = xx;
或者是class.setXXX();
的方式去賦值並不是每次都那麼必要,這時候可以使用constructor
直接在Person
class
中先將初始化
的部分寫好。
創造它的方法很簡單,格式:
權限修飾符 類名稱(){}
如下:
class Person {
String name;
int age;
Public Person(String n, int a) {
name = n;
age = a;
}
下略
}
透過這樣的方式去定義Person
class
時,就可以在實例化
這個class
時,直接將參數
代入後面的()
中
如下:
public class PersonTest {
public static void main(String[] args) {
Person person = new Person("Jack", 20);
System.out.println(person.getName()); // Jack
}
}
這樣在宣告時可以節省不少時間~~~
前面有提到constructor
是class
的一個成員(其二是屬性及方法),當定義class
時沒有特別寫時,其實Java也會自動創建一個沒有任何參數
和內容
的constructor
。
例如這樣:
class Person {
String name;
int age;
Person() {
}
下略
}
並且當沒有寫權限修飾符
時,它會默認和class
的權限相同。
this
指的是”這”,在Java中的this
指的是當前物件
內
的屬性
、方法
、構造器
前面在定義Person
的setName
方法或者是透過constructor
在替屬性
的值初始化
時,故意將參數寫成單一個字母n
和a
,這樣的命名方式其實不是那麼恰當,因為一般不管是在class
、屬性
、方法
、變數
、 參數
等命名時,都會盡量以符合
這個方法的用途或者是符合
這個變數是代表什麼去進行命名
。
錯誤範例:
class Person {
private String name;
public void setName(String name) {
name = name;
}
public String getName() {
return name;
}
}
若是今天用這樣的方式去對name
進行賦值時,當使用getName()
去取得name
的值時,永遠只會得到null
,因為setName()
中的name
,所對應的都會是參數中的name
而不是屬性
的name
,這時候this
就派上用場了。
this的使用方式:
class Person {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
當在setName
中使用this.name
時,這時候它所指的就會是Person
class
中的name
。
this
除了能夠指定物件本身的屬性
外,也可以指定方法
和構造器
。
如下:
class Person {
private String name;
public void eat() {
System.out.println("吃飽飯好開心");
this.sleep();
}
public void sleep() {
System.out.println("來去睡覺囉");
}
public String getName() {
return this.name;
}
}
但是一般如果沒有遇到和參數
相同的命名時,在class
中調用自己的屬性
和方法
時,可以省略不寫。
當使用this
是指向構造器
時,使用的方式和屬性
及方法
不太一樣
如下:
class Person {
String name;
int age;
public Person() {
}
public Person(String name) {
this();
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
}
有沒有發現這個Person
的構造器
似曾相識的感覺? 沒錯,構造器
也可以使用overload
的方式去定義多個不同的構造器
。
在構造器
中使用this
時,有幾個要求:
構造器
的第一行使用參數
的構造器
中使用this()
)以上方的例子來看,在構造器
中使用必須使用this();
的方式去調用,並且當帶有參數
時,它會去調用符合
的構造器
進而減少程式碼
重複的問題。