第四章、对象与类
4.1. 封装性
- 使用get方法获取对象私有属性时需要注意:不要返回可变对象的引用。
class emp{
private Date date;
public Date getDate(){
return this.date;
}
}
--------------------
Date date1=new emp().getDate();
此时date1和emp中的date指向的是同一块区域,这样的话就破坏了封装性,其他对象在外部也可对其私有属性进行修改。
改进方法:
对返回的私有对象做一个克隆即可:
class emp{
private Date date;
public Date getDate(){
return date.clone();
}
}
- 值得注意的是:一个类可以直接访问该类内部所有对象的私有域。
- 私有方法的用处:常常作为内部复杂算法的分部实现,是作为对象内部某个复杂方法的几个实现步骤之一。
- 静态方法的适用场景:作为工具类我只需要用你的方法我不需要对象、我只需要给你传参调用方法即可,无需使用对象属性。
4.3 类路径
- classPath:是所有包含类文件路径的集合,%java_home%/lib,找类时会在该classPath路径下找以及当前目录下。
- path: java开发中所用得到的开发工具,jdb、javac、java等
- java_home: jdk在本机存放位置。
4.10 类设计技巧
- 使用私有数据。
- 保证对数据的初始化。
- 不要在类中使用过多基本数据类型,可以将这些数据类型放到一个类中,便于维护。比如address类包含诸多基本数据类型。
- 不是所有实例域都可以有set和get方法,有些实例域一旦创建对象后就不能再更改了,比如入职时间。
- 将职责较为复杂的类进行分解:对于一副牌可以进行shuffle、draw等等操作,同时对于单张牌可以看花色、看点书等操作,这两个类就应该分开创建,而不是冗余到一起。
- 类名和属性名要跟类的作用相关:使用动词+名词、使用形容词+名词等。
- 将通用方法放到父类,将特殊方法放到子类。
五、继承
继承:is-a的关系,本质上是子类对父类信息的扩展:animal-person-driver
5.1.2 多态
对态就是指一个对象可以同时有多种类型,其编译类型和运行时类型不同,也可以说是子类对象也可以是父类对象的一种。
调用对象方法时会自动调用其运行时类型的方法。
5.1.4 final
阻止继承,自然无多态。
- final修饰类:该类没有子类,类中方法都为final,但实例域并不是。
- final修饰方法:该方法不能被子类重写。
- final修饰属性:该属性为实例域那么只能声明时赋值、代码块中赋值、构造函数中赋值。该属性为局部变量则不能被更改。
5.1.5 强制类型转换
- 子类转成父类时一定主要要使用instanceof关键字使得代码更加健壮。
- 一般情况下少用强制类型转换:1. 子类应该能够使用自己的方法就可以搞定,没必要显式的直接调用父类方法。2. 开销大。
5.1.6 抽象类
- 我认为抽象类是一种模板类的设计思想,它将比较通用的类抽象出来,供子类来使用,子类可以获取抽象类的一般通用的数据和方法,同时也可以在其基础上扩展自己的行为和属性,也可以理解站在巨人的肩膀上做事儿。
- 我认为接口是一种行为规范的设计思想,将一些方法设为接口,供不同的类来给予特定的实现,但实现接口的类必须遵循接口定的规范,这样大大提高代码的整洁、代码的统一。
- 基类和抽象类的区别:我认为就是抽象的程度。
- 同时接口可以有多继承和多实现能够很好弥补java单继承的劣势。
5.2.1 equals方法
使用equals方法的一个误区:在子类中调用equals方法时,首先先调用父类的equals方法,如果父类的域不相等的话更别提这两个对象能相等了。针对基本数据类型有null的情况可以使用Objects.equals(a,b)方法.
下方代码就是错误示范:
package testCodeSamples;
import org.junit.jupiter.api.Test;
import java.util.Objects;
/*
* @author lzy
* @version 1.0
* */
public class equals_ {
@Test
public void testEqualsExtend(){
testEqualsSon testEqualsSon1=new testEqualsSon();
testEqualsSon testEqualsSon2=new testEqualsSon();
testEqualsSon2.name="123123";
System.out.println(testEqualsSon1.equals(testEqualsSon2));//true
}
}
class testEquals{
public String name ="testEqualsFather";
}
class testEqualsSon extends testEquals{
public String age="11";
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof testEqualsSon)) return false;
testEqualsSon that = (testEqualsSon) o;
return Objects.equals(age, that.age);
}
@Override
public int hashCode() {
return Objects.hash(age);
}
}
5.3.1 泛型数组
数组:一旦确定大小就不能更改。
集合:可以很方便进行扩容。