完成:类与对象

master
高宏宇 3 years ago
parent 074b24edce
commit 83d5c1a56d

@ -230,7 +230,7 @@ public class ArrayTest3 {
}
```
**注意:可以在函数中改变数组内部元素的值但是无法改变数值本身的引用例如changeArray函数虽然数组变量是引用变量类似指针。**
**注意:可以在函数中改变数组内部元素的值。**
### 2.7. 对数组元素排序

@ -404,17 +404,209 @@ public class CircleWithPrivateDataFields {
## 6. 对象作为函数参数
值传递和引用传递
如果是基本类型的变量那么使用的是值传递上一章已经说明了。如果是引用类型大写的类型对象类型那么使用的是引用传递。引用传递如同C语言的指针一样我们可以在函数的内部改变引用对象内部成员的值。
```java
class CircleWithPrivateDataFields {
/** The radius of the circle */
private double radius = 1;
/** The number of the objects created */
private static int numberOfObjects = 0;
/** Construct a circle with radius 1 */
CircleWithPrivateDataFields() {
numberOfObjects++;
}
/** Construct a circle with a specified radius */
public CircleWithPrivateDataFields(double newRadius) {
radius = newRadius;
numberOfObjects++;
}
// get radius
public double getRadius() {
return radius;
}
// set radius
public void setRadius(double radius) {
this.radius = radius;
}
/** Return numberOfObjects */
public static int getNumberOfObjects() {
return numberOfObjects;
}
/** Return the area of this circle */
public double getArea() {
return radius * radius * Math.PI;
}
}
public class TestPassObject {
/** Main method */
public static void main(String[] args) {
// Create a Circle object with radius 1
CircleWithPrivateDataFields myCircle = new CircleWithPrivateDataFields(1);
// Print areas for radius 1, 2, 3, 4, and 5.
int n = 5;
printAreas(myCircle, n);
// See myCircle.radius and times
System.out.println("\n" + "Radius is " + myCircle.getRadius());
System.out.println("n is " + n);
}
/** Print a table of areas for radius */
public static void printAreas(CircleWithPrivateDataFields c, int times) {
System.out.println("Radius \t\tArea");
while (times >= 1) {
System.out.println(c.getRadius() + "\t\t" + c.getArea());
c.setRadius(c.getRadius() + 1);
times--;
}
}
}
```
`printAreas`函数接受两个参数,第一个参数是`CircleWithPrivateDataFields`类型的引用变量,第二个参数是循环的次数;主函数先生成一个`CircleWithPrivateDataFields`对象,然后使用`printAreas`函数;在`printAreas`函数内部进行了5次循环每次通过`CircleWithPrivateDataFields`的`setRadius`函数使得`CircleWithPrivateDataFields`对象的半径+1然后再打印`CircleWithPrivateDataFields`对象的面积;当`printAreas`函数执行完成后,我们在主函数中打印`CircleWithPrivateDataFields`对象`c`的半径发现半径已经变成了6初始值是15次累加后变成6
这个例子证明如果是引用变量在函数内部可以改变传入对象的成员变量值其实这里使用的是setter函数改变半径的因为半径是私有的如果半径是public的使用直接赋值也可以改变。
如果我么在`printAreas`函数执行完成后打印n这个变量作为参数times传入`printAreas`函数会发现这个值还是5因为基本类型的变量使用的是值传递。
## 7. 对象数组
## 8. Immutable 类与对象
上一章我们学了数组,不过数组中元素的类型是基本类型。其实数组也是一个特殊的类(其变量也是引用变量),那么我们也可以在函数内部改变数组元素的值,无论数组内部是基本类型还是引用类型。
数组元素是基本类型:
```java
public class Test {
public static void main(String[] args) {
int a[] = { 1, 2, 3, 4, 5 };
System.out.printf("Before run changeArray, a[0] is %d\n", a[0]);
changeArray(a);
System.out.printf("After run changeArray, a[0] is %d\n", a[0]);
}
static void changeArray(int a[]) {
a[0] = 1000;
}
}
```
运行后我们发现a[0]的值已经被修改成了1000这种例子前面也遇到过。
下面看看数组中的元素是引用类型的情况,借用上个例子的`CircleWithPrivateDataFields`类型。
```java
public class TotalArea {
/** Main method */
public static void main(String[] args) {
// Declare circleArray
CircleWithPrivateDataFields[] circleArray;
// Create circleArray
circleArray = createCircleArray();
// Print circleArray and total areas of the circles
printCircleArray(circleArray);
}
/** Create an array of Circle objects */
public static CircleWithPrivateDataFields[] createCircleArray() {
CircleWithPrivateDataFields[] circleArray = new CircleWithPrivateDataFields[5];
for (int i = 0; i < circleArray.length; i++) {
circleArray[i] = new CircleWithPrivateDataFields(Math.random() * 100);
}
// Return Circle array
return circleArray;
}
/** Print an array of circles and their total area */
public static void printCircleArray(CircleWithPrivateDataFields[] circleArray) {
System.out.printf("%-30s%-15s\n", "Radius", "Area");
for (int i = 0; i < circleArray.length; i++) {
System.out.printf("%-30f%-15f\n", circleArray[i].getRadius(), circleArray[i].getArea());
}
System.out.println("-----------------------------------------");
// Compute and display the result
System.out.printf("%-30s%-15f\n", "The total areas of circles is", sum(circleArray));
}
/** Add circle areas */
public static double sum(CircleWithPrivateDataFields[] circleArray) {
// Initialize sum
double sum = 0;
// Add areas to sum
for (int i = 0; i < circleArray.length; i++)
sum += circleArray[i].getArea();
return sum;
}
}
```
1. 数组可以作为函数的返回值,例如`createCircleArray`函数生产了5个元素的数组其半径都随机的。
2. `CircleWithPrivateDataFields`和`sum`函数都是数组作为参数。
你可以在函数中改变数组中引用对象内部成员的值,如同**对象作为函数参数**中一样。
## 8. Immutable 类与对象(了解)
If the contents of an object cannot be changed once the object is created, the object is called an immutable不变的 object and its class is called an immutable class. If you delete the set method in the Circle class in Listing 8.10, the class would be immutable because radius is private and cannot be changed without a set method.
这个概念需要了解我们目前使用到的Immutable类是Spring下一章中所有的 warp 类型也是 Immutable。
## 9. 变量作用域
The scope of instance and static variables is the entire class. They can be declared anywhere inside a class.
The scope of a local variable starts from its declaration and continues to the end of the block that contains the variable. A local variable must be initialized explicitly before it can be used.
## 10. This关键字
### 10.1. 构造函数重载
The this keyword is the name of a reference that refers to an object itself. One common use of the this keyword is reference a classs hidden data fields. Another common use of the this keyword to enable a constructor to invoke another constructor of the same class.
```java
public class Circle {
public double radius;
public Circle() {
this(1.0);
}
public Circle(double radius) {
this.radius = radius;
}
}
```
上个例子有两个构造函数这是构造函数的overload。在`public Circle(double radius)` 这个构造函数中,因为参数列表中有一个`radius`,这时在构造函数内部如果使用`radius`这个变量,则是指该函数参数列表中的`radius`变量。那么类`Circle`中的`radius`变量就无法直接访问了。因此使用this关键字代表**本对象**,那么`this.radius`就代表`Circle`的成员变量`radius`。最后`this.radius = radius;`就没有歧义了。
不带参数的构造函数`public Circle()`可以调用其他构造函数这里用this(1.0),表示调用该类中带参数的构造函数。
## 11. 本章重点

Loading…
Cancel
Save