66
77例如 子类 manager可以派生出executive类
88
9- ![ 类对象] ( C:\Users\modige\AppData\Roaming\Typora\typora -user-images\image -20211003111913690.png )
9+ ![ 类对象] ( C:%5CUsers%5Cmodige%5CAppData%5CRoaming%5CTypora%5Ctypora -user-images%5Cimage -20211003111913690.png )
1010
1111### 5.1.2 多态
1212
2626
2727对象方法调用过程详细描述
2828
29- 1 . 假设调用x.f(name),编译器会调用类中所有名为f 以及 超类中 属性为public 且名为 f的方法 如 f(int a) f(String a)等
29+ 1 . 假设调用x.f(name),编译器会调用类中所有名为f 以及 超类中 属性为public 且名为 f的方法 如 f(int a) f(String a)等
30302 . 接着检查候选方法的参数类型,选择一个与提供的参数类型相同的方法,例如如果是x.f("modige"),编译器会选择f(String a),如果没有匹配的类型,则检查参数类型转换之后是否有满足的,都没有则报错,这个过程称为** 重载解析**
31313 . 如果是private static final修饰的方法,或者构造器,那么编译器将可以准确地知道改运行哪个方法,这种调用方式称为** 静态绑定** ,** 与此对应的是动态绑定** ,上述例子则是动态绑定
32324 . 当程序运行并采用动态绑定的方法,虚拟机每次都要按照12进行寻找,时间开销较大,因此虚拟机为每个类预设一个方法表,因此调用时虚拟机只需查表即可
4747* 除了抽象方法,抽象类也可以包含具体的方法和数据
4848* 抽象方法充当着占位的角色
4949
50- 宏观地说,每个人都有姓名性别之类的属性,所以之前提到的父类Employee也可以有自己的父类Person,![ image-20211003152218735] ( C:\Users\modige\AppData\Roaming\Typora\typora -user-images\image -20211003152218735.png )
50+ 宏观地说,每个人都有姓名性别之类的属性,所以之前提到的父类Employee也可以有自己的父类Person,![ image-20211003152218735] ( C:%5CUsers%5Cmodige%5CAppData%5CRoaming%5CTypora%5Ctypora -user-images%5Cimage -20211003152218735.png )
5151
5252由于person的子类太多,所以很多方法不方便具体写出,比如如果有一个getDescription方法用来返回对每个类的简短,那么对于额employee,可以返回“这是一个工资为1000的员工”,对于student,可以返回“这是一个成绩不错的学生”,如此一来该方法就不适合返回具体内容了
5353
5757public abstract class Person {
5858 public abstract String getDescription ();
5959}
60-
6160```
6261
6362扩展抽象方法可以有两种选择
@@ -79,7 +78,7 @@ Person p = new Employee() //正确
7978* 仅对本类可见 private
8079* 对所有类可见 public
8180* 对本包和所有子类可见 protected
82- * 对本包可见 默认(即没有修饰符)
81+ * 对本包可见 默认(即没有修饰符)
8382
8483## 5.2 Object:所有类的超类
8584
@@ -89,8 +88,6 @@ Person p = new Employee() //正确
8988
9089判断两个对象是否具有相同的引用
9190
92-
93-
9491``` java
9592 public boolean equals(Object otherObject){
9693 if (this == otherObject) return true ;
@@ -101,14 +98,11 @@ Person p = new Employee() //正确
10198 }
10299```
103100
104-
105-
106101### 5.2.2 相等测试与继承
107102
108103### 5.2.3 HashCode方法
109104
110105* 散列码是由对象导出的一个整型值,散列码是没有规律的
111-
112106* 由于hashCode方法定义在Object方法中,所以每个对象都有一个默认的散列码--其存储地址
113107
114108``` java
@@ -121,80 +115,72 @@ Person p = new Employee() //正确
121115 System . out. println(t. hashCode() + " " + tb. hashCode());
122116```
123117
124- | 值 | hashCode |
125- | ---- | --------- |
126- | s | 2524 |
127- | sb | 284720968 |
128- | t | 2524 |
129- | tb | 214126413 |
118+ | 值 | hashCode |
119+ | -- | --------- |
120+ | s | 2524 |
121+ | sb | 284720968 |
122+ | t | 2524 |
123+ | tb | 214126413 |
130124
131125* s与t的hashCode相同是因为字符串的散列码是根据字符串内容生成的
132-
133126* sb与tb不同是因为StringBuffer类没有定义hashCode方法,所以输出的是他们的存储地址
127+ * 定义hashCode方法时需要合理地组合实例域的散列码
134128
135- * 定义hashCode方法时需要合理地组合实例域的散列码
136-
137- ``` java
138- public int hashCode(){
139- return 7 + name. hashCode()+ 11 + new Double (salary). hashCode() + 13 + new Date (). hashCode();
140- }
141- ```
142-
143- ** 由上述例子可见,两个实例域对应相等的对象会返回相同的hashCode()值**
129+ ``` java
130+ public int hashCode(){
131+ return 7 + name. hashCode()+ 11 + new Double (salary). hashCode() + 13 + new Date (). hashCode();
132+ }
133+ ```
144134
145- ** 两个实例域不同的对象也可能返回相等的hashcode值 **
135+ ** 由上述例子可见,两个实例域对应相等的对象会返回相同的hashCode()值 **
146136
147- ** hashCode 与 Equals的定义必须一致,如果x.equals(y)返回true,那么x.hashCode()就必须返回与y.hashCode()相同的值 **
137+ ** 两个实例域不同的对象也可能返回相等的hashcode值 **
148138
149- 例如,如果equal比较员工id,hashCode必须散列id,而不是姓名或存储地址
139+ ** hashCode 与 Equals 的定义必须一致,如果x . equals(y)返回 true ,那么x . hashCode()就必须返回与y . hashCode()相同的值 **
150140
151- ### 5.2.4 ToString方法
141+ 例如,如果equal比较员工id,hashCode必须散列id,而不是姓名或存储地址
152142
143+ #### 5.2 . 4 ToString 方法
153144* 它用于返回表示对象值的字符串
154-
155145* 当对象与一个字符串通过+ 连接时,编译器会调用toString方法
156-
157146* 输出对象时,编译器会调用toStrong方法
147+ * 也可以在调试时使用toString方法以此观察类的状态
148+
149+ *
158150
159- * 也可以在调试时使用toString方法以此观察类的状态
151+ 例如, Employee 类的可以这样写
160152
161- *
153+ ```java
154+ public String toString(){
155+ return getClass(). getName()+ " "
156+ + " [name=" + name + " ,Salary="
157+ + salary + " ,hireDay="
158+ + hireDay + " ]" ;
159+ }
162160
163- 例如,Employee类的可以这样写
161+ // 输出:Employee [name=modige,Salary=1000.0,hireDay=Sun Oct 03 16:16:34 CST 2021]
162+ ```
164163
165- ``` java
166- public String toString(){
167- return getClass(). getName()+ " "
168- + " [name=" + name + " ,Salary="
169- + salary + " ,hireDay="
170- + hireDay + " ]" ;
171- }
172-
173- // 输出:Employee [name=modige,Salary=1000.0,hireDay=Sun Oct 03 16:16:34 CST 2021]
174- ```
164+ 子类可以改写父类的toString方法
175165
176- 子类可以改写父类的toString方法
166+ ```java
167+ public String toString(){
168+ return super . toString()+ " [bonus=" + bonus+ " ]" ;
169+ }
177170
178- ``` java
179- public String toString(){
180- return super . toString()+ " [bonus=" + bonus+ " ]" ;
181- }
182-
183- // Manager [name=modige,Salary=1000.0,hireDay=Sun Oct 03 16:19:34 CST 2021][bonus=0.0]
184- ```
171+ // Manager [name=modige,Salary=1000.0,hireDay=Sun Oct 03 16:19:34 CST 2021][bonus=0.0]
172+ ```
185173
186174## 5.3 泛型数组列表ArrayList
187175
188176* ArrayList 是一个采用类型参数的泛型类
189-
190177* 定义一个长度未知的数组
191-
192178* 当提前定义的空间用完后,系统会自动创建一个更大的数组,并将之前的数据复制到新数组中
193-
194179* 如果提前知道长度,可以使用ensureCapacity指定长度
180+
195181## 5.4 对象包装器与自动打包
196182
197- 有时候需要将int这类基本数据类型转换为对象。所有的基本数据类型都有对应的类 例如Integer对应int。通常这种类称为包装器(wrapper)
183+ 有时候需要将int 这类基本数据类型转换为对象。所有的基本数据类型都有对应的类 例如Integer 对应int 。通常这种类称为包装器(wrapper)
198184
199185* Integer
200186* Long
@@ -208,11 +194,12 @@ Person p = new Employee() //正确
208194
209195其中前六个派生于超类Number
210196
211- 在ArrayList<>的尖括号中不允许出现基本数据类型,就是说不允许写成ArrayList< int > ,这时就需要Integer包装器
197+ 在ArrayList<> 的尖括号中不允许出现基本数据类型,就是说不允许写成ArrayList ,这时就需要Integer 包装器
212198
213199在实际编程中,编译器会将list. add(3 )自动转换成list. add(new Integer (3 ))
214200
215201这种变换称为** 自动打包** ,对应的是自动拆包
202+
216203## 5.5 参数数量可变的方法
217204
218205例如
@@ -235,7 +222,7 @@ System.out.println("%a %b"a,b);
235222 }
236223```
237224
238- 形参里的省略号...表示可以传入任意数量的对象
225+ 形参里的省略号...表示可以传入任意数量的对象
239226
240227## 5.6 枚举类
241228
@@ -262,18 +249,13 @@ public enum Size{
262249
263250### 5.7.3分析类
264251
265-
266-
267-
268-
269252## 5.8 继承设计的技巧
270253
271254* 将公共操作和域放在超类
272255* 不要使用受保护的类
273256* 使用继承实现 is-a 关系
274257* 除非所有继承的方法都有意义,否则不要使用继承
275258* 覆盖方法时不要改变预期的行为
276- * 使用多态而非类型信息
259+ * 使用多态而非类型信息
277260* 不要过多地使用反射
278- *
279-
261+ *
0 commit comments