2021/12/28组会

2012/12/28(第4章 类)

1 用var声明局部变量

p109

在java10中可以利用var 来声明变量类型 ide会自动推导类型 (类似c++中的auto类型)

例如

Employee harry = new Employee("Harry Hacker");

利用var

var harry = new Employee("Harry Hacker");

2 null值的应用

p109

对一个被复制为null的变量调用方法会引起NullPointException异常

LocalDate birthday = null;
String s = birthday.toString();

这个错误类似数组越界,是很严重的错误,对于这个错误有两种解决方法,“宽容型”和“严格型”

2.1 宽容型:

发现变量是null值时,使其变成一个其他的值,在java9中提供了一个方法

public Employee(String n, double s, int year, int month, int day)
{
    name = Objects.requireNonNullElse(n,"unknow");//如果name值为null,则改为unknown
    ...
}

2.2 严格型:

发现变量是null值时,直接报错,在java9中提供了一个方法

public Employee(String n, double s, int year, int month, int day)
{
    Objects.requireNonNull(n,"name can't be null");
    name = n;
    ...
}

这个方法看起来没啥用,因为还是会出NullPointException的报错,但是这个报错会提供这个问题的描述和问题所处位置

3 隐式参数和显式参数

p110

举例对于一个对象的方法调用

employee007.raiseSalary(5);	

前面的对象emploee007就是隐式参数(也称为方法的调用者),后面括号中的数值就是现式参数

4 封装的优点

p111

1,封装实现了getter和setter方法,防止类内的变量被随意修改,同时也可以设置getter和setter的权限等级来实现分级访问或者修改

2,同时,对于封装好的方法,如果在类内的某些参数发生了改变,我们只需要调整getter或setter函数便可保证整个代码继续可用,而不需要去找到每个可能使得代码异常的地方,如下

class Employee
{
	private string name;
	
	public string getName()
	{
		return name;
	}
}

如果将name改成firstname和lastname的组合,也只需要更改getter方法,外界对方法怎么实现并不在意

class Employee
{
	private string firstName;
	private string lastName;
    
	public string getName()
	{
		return firstName + " " + lastName;
	}
}

3,同时,getter和setter也可用于错误检查,例如setSalary可检查在设置薪资时是否为小于0的异常值

public void setSalary(int s)
{
	if(s <= 0)
	{
		system.out.println("Setting of salary in fault!");
		return;
	}
	salary = s;
	
}

警告 不要写返回可变对象引用的getter(返回 可变对象引用 的getter) 如下

class Employee
{
	private Date hireDay;
	...
	
	public Date getHireDay()
	{
		return hireDay;
	}
	...
}


public static void main(string[] arg)
{
    Employee harry = ...;
    Date d = harry.getHireDay();
    double tenYearInMilliSeconds = 10*365.25*24*60*60*1000;
    d.setTime(d.getTime() - (long) tenYearsInMilliseconds);
    //let's get Harry ten years of added seniority
    
}

在上面的代码中并没有写Employee中hireday的setter,但是由于返回了类内的hireday的引用,可以声明一个Date d来接受这个引用,再利用Date中的setter更改这个引用指向的值,这就破坏了封装的意义也破坏了hireday的private权限
image

如果需要返回可变对象引用,应当使用克隆后的副本返回,防止上述问题发生

class Employee
{
	private Date hireDay;
	...
	
	public Date getHireDay()
	{
		return (Date) hireDay.clone();
	}
	...
}
posted @ 2021-12-20 00:19  落悠  阅读(37)  评论(0编辑  收藏  举报