CoreJava(第四章)對象和類-02

4.3用戶自定義類

通常這些類沒有 main 方法 , 卻有自己的實例域和實例方法 。

(實例域:定義類時的最外層的那兩個大括號那個範圍。
實例方法:沒有static關鍵字的都叫實例方法。有關鍵字的叫類方法。)

4.3.1需求

1.構造一個數組,填入三個員工的信息。

2.將每個員工的工資提高5%。

3.將每個員工的信息打印出來。

4.3.2實現

package com.eleven.oop;

import java.time.LocalDate;

/**
 * 將員工的工資提高5%
 * 
 * @author sywangu
 *
 */
public class EmployeeTest {
	public static void main(String[] args) {
		// 1.構造一個數組,填入三個僱員對象
		Employee[] staff = new Employee[3];
		staff[0] = new Employee("伊萊文", 30000.0, 1989, 12, 15);
		staff[1] = new Employee("Eleven", 40000.0, 1987, 10, 21);
		staff[2] = new Employee("Keep", 50000.0, 1980, 11, 21);
		// 2.將每個僱員的薪水提高5%
		for (Employee e : staff) {
			e.raiseSaraly(5);
		}
		// 3.打印出每個僱員的信息
		for (Employee e : staff) {
			System.out.println("員工" + "姓名:" + e.getName() + "工資:" + e.getSalary() + "薪水:" + e.getHireday());
		}
	}

}

class Employee { // Employee是實例
	private String name; // 實例域
	// 其中private Double salary和private LocalDate
	// hireday它們兩個的實例域的本身就是對象。name域是String類對象,hireDay域是LocalDate類對象
	private Double salary;
	private LocalDate hireday; // 僱傭

	/**
	 * 如果有 1000 個 Employee 類的對象 , 則有 1000 個實例域 id 。 但是 , 只有一 個靜態域 nextld 。
	 */
	// 實例域:Java定義類中的屬性;靜態域:在屬性前面加上static關鍵字
	private static int nextId = 1; // 靜態域id
	private int id; // 實例域id

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

	public LocalDate getHireday() {
		return hireday;
	}

	public void setHireday(LocalDate hireday) {
		this.hireday = hireday;
	}

	@Override
	public String toString() {
		return "Employee [name=" + name + ", salary=" + salary + ", hireday=" + hireday + "]";
	}

	// 一個構造器和4個方法,其中構造器和類名要相同
	public Employee(String n, Double s, int year, int month, int day) {
		super();
		this.name = n;
		this.salary = s;
		this.hireday = LocalDate.of(year, month, day);
	}

	public Employee() {
		super();
	}

	/**
	 * 提高工資的5%
	 * 
	 * @param byPercent
	 */
	public void raiseSaraly(double byPercent) {
		double raise = salary * byPercent / 100; // 提高後的薪水
		salary += raise; // 原有的薪水 + 提高後的薪水
	}

	/**
	 * 比較兩個員工的equals方法
	 * 
	 * @param other
	 * @return
	 */
	public boolean equals(Employee other) {
		return name.equals(other.name);
	}
	
	public void setId() {
		id = nextId;
		nextId++;
	}
}

4.3.3輸出

員工姓名:伊萊文工資:31500.0薪水:1989-12-15
員工姓名:Eleven工資:42000.0薪水:1987-10-21
員工姓名:Keep工資:52500.0薪水:1980-11-21

4.4構造器

構造器與類同名
• 每個類可以有一個以上的構造器
• 構造器可以有0 個 、 1 個或多個參數
• 構造器沒有返回值
• 構造器總是伴隨着new 操作一起調用

4.5隱式參數和顯式參數

隱式參數:出現在方法名前面的對象,隱式參數用關鍵字this表示。
在這裏插入圖片描述

顯式參數:方法名後面括號中的數值。
在這裏插入圖片描述

4.5.1完整代碼

package com.eleven.oop;

import java.time.LocalDate;

public class ShowHiddenParam { // 隱式參數
	private String name;
	private Double salary;
	private LocalDate hireday;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

	public LocalDate getHireday() {
		return hireday;
	}

	public void setHireday(LocalDate hireday) {
		this.hireday = hireday;
	}

	// 出現在方法名前面的ShowHiddenParam是隱式參數
	public void raiseSaraly(double byPercent) { // 方法名括號後面的數值:double byPercent是一個顯示參數
		// double raise = salary * byPercent / 100;
		// salary += raise;
		// 關鍵字this表示隱式參數,有人喜歡這種方式,因爲這樣可以將實例域與局部變量明顯地區分開來
		double raise = this.salary * byPercent / 100;
		this.salary += raise;
	}

}

4.6final實例域

被定義爲final時,這個值不會被修改,同樣,也沒有set方法。

final 修飾符大都應用於基本 ( primitive ) 類型域, 或不可變 ( immutable )類的域 ( 如果類中的每個方法都不會改變其對象 , 這種類就是不可變的類。 例如 , String 類就是一個不可變的類 ) 。

4.7靜態域

4.7.1需求

假如有 1000 個 Employee 類的對象 , 則有 1000 個實例域 id 。 但是 , 只有一 個靜態域 nextld 。

在這裏插入圖片描述

4.7.2完整代碼

package com.eleven.oop;

import java.time.LocalDate;

/**
 * 將員工的工資提高5%
 * 
 * @author sywangu
 *
 */
public class EmployeeTest {
	public static void main(String[] args) {
		// 1.構造一個數組,填入三個僱員對象
		Employee[] staff = new Employee[3];
		staff[0] = new Employee("伊萊文", 30000.0, 1989, 12, 15);
		staff[1] = new Employee("Eleven", 40000.0, 1987, 10, 21);
		staff[2] = new Employee("Keep", 50000.0, 1980, 11, 21);
		// 2.將每個僱員的薪水提高5%
		for (Employee e : staff) {
			e.raiseSaraly(5);
		}
		// 3.打印出每個僱員的信息
		for (Employee e : staff) {
			System.out.println("員工" + "姓名:" + e.getName() + "工資:" + e.getSalary() + "薪水:" + e.getHireday());
		}
	}

}

class Employee { // Employee是實例
	private String name; // 實例域
	// 其中private Double salary和private LocalDate
	// hireday它們兩個的實例域的本身就是對象。name域是String類對象,hireDay域是LocalDate類對象
	private Double salary;
	private LocalDate hireday; // 僱傭

	/**
	 * 如果有 1000 個 Employee 類的對象 , 則有 1000 個實例域 id 。 但是 , 只有一 個靜態域 nextld 。
	 */
	// 實例域:Java定義類中的屬性;靜態域:在屬性前面加上static關鍵字
	private static int nextId = 1; // 靜態域id
	private int id; // 實例域id

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

	public LocalDate getHireday() {
		return hireday;
	}

	public void setHireday(LocalDate hireday) {
		this.hireday = hireday;
	}

	@Override
	public String toString() {
		return "Employee [name=" + name + ", salary=" + salary + ", hireday=" + hireday + "]";
	}

	// 一個構造器和4個方法,其中構造器和類名要相同
	public Employee(String n, Double s, int year, int month, int day) {
		super();
		this.name = n;
		this.salary = s;
		this.hireday = LocalDate.of(year, month, day);
	}

	public Employee() {
		super();
	}

	/**
	 * 提高工資的5%
	 * 
	 * @param byPercent
	 */
	public void raiseSaraly(double byPercent) {
		double raise = salary * byPercent / 100; // 提高後的薪水
		salary += raise; // 原有的薪水 + 提高後的薪水
	}

	/**
	 * 比較兩個員工的equals方法
	 * 
	 * @param other
	 * @return
	 */
	public boolean equals(Employee other) {
		return name.equals(other.name);
	}
	
	public void setId() {
		id = nextId;
		nextId++;
	}
}

4.8靜態常量

相比靜態變量,靜態常量用的比較多些。

package com.eleven.oop;

/**
 * 靜態常量
 * 
 * @author sywangu
 *
 */
public class StaticConstant {

	// 有static關鍵字的叫靜態域,反之沒有叫實例域
	public static final double PI = 3.1415926; // 定義了一個靜態常量

	public static void main(String[] args) {
		// 可以通過StaticConstant類來訪問裏面的PI
		System.out.println(StaticConstant.PI);
	}

}

4.9靜態方法

  • 0.前面有關鍵字static,就叫靜態方法,反之爲非靜態方法。
  • 1.靜態方法不能直接向對象實施操作。
  • 2.靜態方法是沒有this參數的方法。(說明不是隱式參數)
  • 3.靜態方法可以訪問自身類中的靜態域。
package com.eleven.oop;

/**
 * 0.前面有關鍵字static,就叫靜態方法,反之爲非靜態方法。
 * 1.靜態方法不能直接向對象實施操作。
 * 2.靜態方法是沒有this參數的方法。(說明不是隱式參數)
 * 3.靜態方法可以訪問自身類中的靜態域。
 * @author sywangu
 *
 */
public class StaticMethod {
	
	public static String getType() {
		return "人類";
	}
	
	public String getName() {
		return "張三";
	}
	
	public static void main(String[] args) {
		// 01靜態方法可以直接使用類名調用
		String type = StaticMethod.getType();	
		System.out.println(type);	// 人類
		
		// 02非靜態方法需要使用實例對象(StaticMethod)調用
		StaticMethod method = new StaticMethod();
		String name = method.getName();
		String type1 = method.getType();	// 當然getType方法也可以通過對象進行調用
		System.out.println("姓名:"+name+",類別:"+type1);	// 姓名:張三,類別:人類
	}

}

4.10main方法

4.10.1需求

程序包含了 Employee 類的一個簡單版本 , 其中有一個靜態域 nextId 和一個靜態方法 getNextId 這裏將 5 個 Employee對象寫入數組 , 然後打印僱員信息 。 最後 , 打印出下一個可用的員工標識碼來展示靜態方法 。

4.10.2實現

package com.eleven.oop;

/**
 * 程序包含了 Employee 類的一個簡單版本 , 其中有一個靜態域 nextId 和一個靜態方法 getNextId 這裏將 5 個 Employee
 * 對象寫入數組 , 然後打印僱員信息 。 最後 , 打印出下一個可用的員工標識碼來展示靜態方法 。
 * 
 * @author sywangu
 *
 */
public class StaticTest {
	public static void main(String[] args) {
		Person[] p = new Person[3];
		p[0] = new Person("伊萊文", 5000.0);
		p[1] = new Person("Keep", 666.8);
		p[2] = new Person("Eleven", 9089.02);

		// 打印所有員工的信息
		for (Person e : p) {
			e.setId();
			System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary=" + e.getSalary());
		}

		// 調用靜態方法
		int n = Person.getNextId();
		System.out.println("下一個id爲:" + n);
	}

}

class Person {
	private static int nextId = 1; // 靜態域nextId = 1
	private int id;
	private String name;
	private double salary;

	// 靜態方法
	public static int getNextId() {
		return nextId; // 返回靜態字段
	}

	public static void setNextId(int nextId) {
		Person.nextId = nextId;
	}

	public int getId() {
		return id;
	}

	public void setId() {
		id = nextId; // 將nextId設置給id
		nextId++;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public Person(String n, double s) {
		name = n;
		salary = s;
		id = 0;
	}

	// 單元測試
	public static void main(String[] args) {
		Person p = new Person("伊萊文", 5000.0);
		System.out.println(p.getName() + " " + p.getSalary());
	}
}

4.11方法參數

**按值調用:**表示方法接收的是調用者提供的值。

**按引用調用:**表示方法接收的是調用者提供的變量地址。

一個方法可以修改傳遞引用所對應的變量值 , 而不能修改傳遞值調用所對應的變量值。

Java 程序設計語言總是採用按值調用。 也就是說 , 方法得到的是所有參數值的一個拷貝, 特別是 , 方法不能修改傳遞給它的任何參數變量的內容。

package com.eleven.oop;

/**
 * 方法參數共有兩種類型:
 * 1.基本數據類型
 * 2.對象引用
 * 其中:
 * 1.一個方法不可能修改一個基本數據類型的參數。
 * @author sywangu
 *
 */
public class MethodParam {
	public static void main(String[] args) {
		double percent = 10;
		abc(percent); // 10.0
		
		Employee harry = new Employee();
		harry = new Employee("伊萊文", 400.0, 1998, 12, 12);
		def(harry);	// Employee [name=伊萊文, salary=1200.0, hireday=1998-12-12]
		
	}

	// 01一個方法不可能修改一個基本數據類型的參數。
	public static void abc(double x) {
		x = x * 3;	// x = 30,當這個方法結束後,參數變量x就不再使用。
	}
	
	// 02對象引用作爲參數則可以實現"提高工資的50%"
	public static void def(Employee e) {
		e.raiseSaraly(50);
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章