Skip to content

Commit deb62b2

Browse files
committed
新增 Java 章节内容:35-返回值,包含商品利润计算及调试方法示例
1 parent 625f765 commit deb62b2

File tree

6 files changed

+244
-1
lines changed

6 files changed

+244
-1
lines changed

src/Java/.DS_Store

0 Bytes
Binary file not shown.

src/Java/chapter02/.DS_Store

2 KB
Binary file not shown.
49.8 KB
Loading
67.3 KB
Loading
86 KB
Loading

src/Java/chapter02/35.md

Lines changed: 244 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,262 @@ footer: 长期招收编程一对一学员!微信:Jiabcdefh, <a href="https:/
3131
- 看例程:商品的其它方法
3232
- 方法调用调试之 Step Into:进入被调用的方法内部继续调试
3333

34-
## 1. 看例程: 让商品自己计算利润的方法
34+
## 1. 看例程: 让商品自己计算利润的方法
35+
36+
既然,我们要计算利润,那就不能是直接编写方法输出在控制台就结束,而应该是计算完成后,返回这个计算值。这就是我们所说的返回值。
37+
38+
::: code-tabs
39+
40+
@tab MerchandiseV2
41+
42+
```java
43+
package com.bornforthis.supermarket;
44+
45+
public class MerchandiseV2 {
46+
47+
public String name;
48+
public String id;
49+
public int count;
50+
public double soldPrice;
51+
public double purchasePrice;
52+
53+
public void describe() {
54+
System.out.println("商品名字叫做" + name + ",id是" + id + "。 商品售价是" + soldPrice
55+
+ "。商品进价是" + purchasePrice + "。商品库存量是" + count +
56+
"。销售一个的毛利润是" + (soldPrice - purchasePrice));
57+
}
58+
59+
// >> TODO 在方法定义中指定方法的返回值类型 double
60+
// >> TODO Java中一个方法只能有一种返回值,如果不需要返回值则用 void 表示
61+
// >> TODO 如果定义了返回值,则必须使用 return 语句返回方法的返回值,return 是 Java 的关键字
62+
// >> TODO 可以认为,返回值必须要能够用来给返回值类型的变量赋值,也就是返回的值要可以给 double 类型的变量赋值
63+
// >> TODO 举个例子:下面👇代码返回的 return profit、return 0 必须要能够给返回值类型变量赋值(public double calculateProfit())中 double 就是返回值类型。那么返回 0 可以吗?——可以!返回 profit 是 double 类型——可以!
64+
public double calculateProfit() {
65+
double profit = soldPrice - purchasePrice;
66+
// >> TODO 这个 return 是代码块里的 return,是 return 所在代码块的最后一个语句
67+
if (profit <= 0) {
68+
return 0;
69+
}
70+
// >> TODO return 语句必须是所在代码块的最后一个语句,否则就是语法错误
71+
return profit;
72+
73+
// >> TODO 一个方法可以有多个返回语句。
74+
}
75+
76+
// >> TODO 返回值如果是基本类型,则要类型完全相同,或者符合类型自动转换规则
77+
public double getCurrentCount() {
78+
return count; // int 可以自动转换、返回给 double
79+
}
80+
81+
// >> TODO 如果不符合规则,可以使用强制类型转换
82+
public int getIntSoldPrice() {
83+
return (int) soldPrice; // double 不能直接给 int,所以需要强制转换。只要转换之后可以给 int 就行,不管是怎么来的。
84+
}
85+
}
86+
```
87+
88+
@tab MerchandiseV2DescAppMain
89+
90+
```java
91+
package com.bornforthis.supermarket;
92+
93+
public class MerchandiseV2DescAppMain {
94+
public static void main(String[] args) {
95+
MerchandiseV2 merchandise = new MerchandiseV2();
96+
97+
merchandise.name = "书桌";
98+
merchandise.soldPrice = 999.9;
99+
merchandise.purchasePrice = 500;
100+
merchandise.count = 40;
101+
merchandise.id = "DESK9527";
102+
103+
merchandise.describe();
104+
}
105+
}
106+
```
35107

108+
:::
109+
110+
- 代码不能放在 return 后面,因为 return 后面,不能放任何其它代码的;
111+
112+
```java
113+
// 下面成立
114+
int a = 1;
115+
return 0;
116+
```
117+
118+
```java
119+
// 下面不成立:Unreachable statement
120+
return 0;
121+
int a = 1;
122+
```
123+
124+
- return 执行到时,整个方法就结束了;
125+
126+
- 就类似 break 的一样,不过 return 的是方法而不是循环;
127+
- 适当的利用 return 有时会有意想不到的效果,比如:提前结束方法;
128+
129+
## 2. 看例程:让超市找出利润最高的商品的方法
130+
131+
::: code-tabs
132+
133+
@tab LittleSuperMarket
134+
135+
```java
136+
package com.bornforthis.supermarket;
137+
138+
public class LittleSuperMarket {
139+
public String superMarketName;
140+
public String address;
141+
public int parkingCount;
142+
public double incomingSum;
143+
public MerchandiseV2[] merchandises;
144+
public int[] merchandiseSold;
145+
146+
// >> 返回值类型可以是类名,这时候实际返回的值就是这个类的引用
147+
public MerchandiseV2 getBiggestProfitMerchandise() {
148+
MerchandiseV2 curr = null;
149+
for (int i = 0; i < merchandises.length; i++) {
150+
MerchandiseV2 m = merchandises[i];
151+
if (curr == null) {
152+
curr = m;
153+
continue;
154+
}
155+
// >> 调用商品中定义的方法,不同的实例调用相同的方法,虽然代码相同,但是每个实例内部的数据不同,所以返回值也不同
156+
double currProfit = curr.calculateProfit();
157+
double newProfit = m.calculateProfit();
158+
if (currProfit < newProfit) {
159+
curr = m;
160+
}
161+
}
162+
return curr;
163+
}
164+
165+
public MerchandiseV2 getBiggestProfitMerchindise2() {
166+
MerchandiseV2 curr = null;
167+
for (int i = 0; i < merchandises.length; i++) {
168+
MerchandiseV2 m = merchandises[i];
169+
if (curr == null) {
170+
curr = m;
171+
} else {
172+
if (curr.calculateProfit() < m.calculateProfit()) {
173+
curr = m;
174+
}
175+
}
176+
}
177+
return curr;
178+
}
179+
}
180+
```
181+
182+
@tab 原本为改动「无需查看」
183+
184+
```java
185+
package com.geekbang.supermarket;
186+
187+
public class LittleSuperMarket {
188+
public String superMarketName;
189+
public String address;
190+
public int parkingCount;
191+
public double incomingSum;
192+
public MerchandiseV2[] merchandises;
193+
public int[] merchandiseSold;
194+
195+
// >> 返回值类型可以是类名,这时候实际返回的值就是这个类的引用
196+
public MerchandiseV2 getBiggestProfitMerchandise() {
197+
MerchandiseV2 curr = null;
198+
for (int i = 0; i < merchandises.length; i++) {
199+
MerchandiseV2 m = merchandises[i];
200+
if (curr == null) {
201+
curr = m;
202+
continue;
203+
}
204+
// >> 调用商品中定义的方法,不同的实例调用相同的方法,虽然代码相同,但是每个实例内部的数据不同,所以返回值也不同
205+
double currProfit = curr.calculateProfit();
206+
double newProfit = m.calculateProfit();
207+
if (currProfit < newProfit) {
208+
curr = m;
209+
}
210+
}
211+
return curr;
212+
}
213+
214+
public MerchandiseV2 getBiggestProfitMerchindise2() {
215+
MerchandiseV2 curr = null;
216+
for (int i = 0; i < merchandises.length; i++) {
217+
MerchandiseV2 m = merchandises[i];
218+
if (curr == null) {
219+
curr = m;
220+
} else {
221+
if (curr.calculateProfit() < m.calculateProfit()) {
222+
curr = m;
223+
}
224+
}
225+
}
226+
return curr;
227+
}
228+
}
229+
```
230+
231+
:::
232+
233+
## 3. 看例程:商品的其它方法
234+
235+
```java {35-37}
236+
package com.bornforthis;
237+
238+
import com.bornforthis.supermarket.LittleSuperMarket;
239+
import com.bornforthis.supermarket.MerchandiseV2;
240+
241+
public class RunLittleSupperMarketAppMain {
242+
public static void main(String[] args) {
243+
// 创建一个小超市类
244+
LittleSuperMarket littleSuperMarket = new LittleSuperMarket();
245+
// 依次给超市的名字,地址,停车位赋值
246+
littleSuperMarket.superMarketName = "有家小超市";
247+
littleSuperMarket.address = "浦东新区世纪大道666号";
248+
littleSuperMarket.parkingCount = 100;
249+
// 给超市200种商品
250+
littleSuperMarket.merchandises = new MerchandiseV2[200];
251+
// 统计用的数组
252+
littleSuperMarket.merchandiseSold = new int[littleSuperMarket.merchandises.length];
36253

254+
// 为了使用方便,创建一个商品数组引用,和littleSuperMarket.merchandises指向同一个数组对象
255+
MerchandiseV2[] all = littleSuperMarket.merchandises;
37256

257+
// 遍历并给200种商品赋值
258+
for (int i = 0; i < all.length; i++) {
259+
// 创建并给商品的属性赋值
260+
MerchandiseV2 m = new MerchandiseV2();
261+
m.name = "商品" + i;
262+
m.count = 200;
263+
m.purchasePrice = Math.random() * 200;
264+
m.soldPrice = m.purchasePrice * (1 + Math.random());
265+
m.id = "ID" + i;
266+
// 用创建的商品,给商品数组的第i个引用赋值,all和小超市的商品数组引用指向的是同一个数组对象
267+
all[i] = m;
268+
}
38269

270+
System.out.println("下面请利润最高的商品自我介绍:");
271+
// >> TODO 返回值可以直接使用,不必赋值给一个变量再使用。
272+
littleSuperMarket.getBiggestProfitMerchandise().describe();
273+
}
274+
}
275+
```
39276

277+
**思考🤔:**为什么 `littleSuperMarket.getBiggestProfitMerchandise().describe();` 可以连续调用?原因是什么?
40278

279+
因为:方法 `littleSuperMarket.getBiggestProfitMerchandise()` 的返回类型是 `MerchandiseV2` 所以是支持的。
41280

42281

43282

283+
## 4. 法调用调试之 Step Into:进入被调用的方法内部继续调试
44284

285+
![](./35.assets/1673767739843-ff17fa35-3080-4cf8-b0ed-d7bcf15a6959.png)
45286

287+
![](./35.assets/1673767778646-ba8f752d-b29a-4030-8e45-4b0929de011a.png)
46288

289+
![](./35.assets/1673767941151-d55ace71-5716-47d7-b49e-463cb52cc5a5.png)
47290

48291

49292

0 commit comments

Comments
 (0)