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);
	}

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