20145206 《Java程序设计》第3周学习总结
教材学习内容总结
第四章
4.1 定义类
class Clothes{
String color;
char size;
}
public class Field {
public static void main(String[] args) {
Clothes sun=new Clothes();
Clothes spring=new Clothes();
sun.color="red";
sun.size='S';
spring.color="green";
spring.size='M';
System.out.printf("sun(%s,%c)%n",sun.color,sun.size);
System.out.printf("spring(%s,%c)%n",spring.color,spring.size);
}
}
在这个Field.java中,定义了两个类,只要有一个类定义,编译程序就会产生一个.class文档。上例中,实际上会产生Field.class与Clothes.class两个文档。
上面这个例子还可以用下面这个方法做:
class Clothes2{
String color;
char size;
Clothes2( String color, char size){
this.color=color;
this.size=size;
}
}
public class Field2 {
public static void main(String[] args) {
Clothes2 sun=new Clothes2("red",'S');
Clothes2 spring=new Clothes2("green",'M');
System.out.printf("sun(%s,%c)%n",sun.color,sun.size);
System.out.printf("spring(%s,%c)%n",spring.color,spring.size);
}
}
使用两个基本的标准类:
1、使用java.util.Scanner
import java.util.Scanner;
public class Guess {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int number = (int) (Math.random()*10);
int guess;
do{
System.out.print("猜数字(0-9):");
guess = scanner.nextInt();
}while(guess!=number);
System.out.println("猜中了");
}
}
在这之前,程序范例都是死的,用户不能加入自己的想法,这个程序可以实现机器与用户之间的交互,让用户输入变量值,这样看起来就智能许多。
2、使用java.math.BigDecimal
import java.math.BigDecimal;
public class DecimalDemo {
public static void main(String[] args) {
BigDecimal operand1 = new BigDecimal("1.0");
BigDecimal operand2 = new BigDecimal("0.8");
BigDecimal result = operand1.subtract(operand2);
System.out.println(result);
}
}
简单来说,使用java.math.BigDecimal类是为了得到更好的精确度,比如计算1.0-0.8时,不用这个类得不到0.2这个结果,使用这个类结果就会是0.2。
==用在对象类型,是比较两个名称是否参考同一对象,而!=正好相反,是比较两个名称是否没参考同一对象。实际上,equals()可以自行定义如何比较两对象的内含值。
4.2 基本类型打包器
Long、Integer、Double、Float、Boolean等类是所谓的打包器,将基本类型打包在对象之中,这样就可以操作这个对象,就像是将基本类型当做对象操作。
public class IntegerDemo {
public static void main(String[] args) {
int data1=10;
int data2=20;
Integer wrapper1=new Integer(data1);
Integer wrapper2=new Integer(data2);
System.out.println(data1/3);
System.out.println(wrapper1.doubleValue()/3);
System.out.println(wrapper1.compareTo(wrapper2));
}
}
Integer提供compareTo()方法,可与另一个Integer对象进行比较,如果打包值相同就返回0,小于compareTo()传入对象打包值就返回-1.
在Java程序代码中,null代表一个特殊对象,任何类声明的参考名称都可以参考至null.
4.3 数组对象
数组在Java中就是对象。声明数组时,就Java开发人员的撰写习惯来说,建议将[]放在类型关键字之后。
public class Score {
public static void main(String[] args) {
int[] scores = {88,81,64,23,12,10,84,79,52,16};
for(int i=0;i<scores.length;i++){
System.out.printf("学生分数:%d %n",scores[i]);
}
}
}
上例中,数组的length属性可以取得数组长度,也就是数组元素的个数。
下面一个例子是二维数组:
public class XY {
public static void main(String[] args) {
int[][] cords = {
{1,2,3},
{4,5,6}
};
for(int x = 0;x<cords.length;x++){
for(int y =0;y<cords[x].length;y++){
System.out.printf("%2d",cords[x][y]);
}
System.out.println();
}
}
}
其实这个范例也是循序地走访二维数组,并没有真正要用索引做什么事。
如果事先不知道元素值,只知道元素个数,那可以使用new关键词指定长度来建立数组,例如:int[] scores=new int[10];在Java中只要看到new,一定就是建立对象,这个语法代表了数组就是对象。
import java.util.Arrays;
public class Score2 {
public static void main(String[] args) {
int[] scores=new int[10];
for(int score:scores){
System.out.printf("%2d",score);
}
System.out.println();
Arrays.fill(scores,60);
for(int score:scores){
System.out.printf("%3d",score);
}
}
}
没有人规定二维数组一定要是矩阵,你也可以建立不规则数组。
数组复制:可以使用System.arraycopy()方法,这个方法会使用原生方式复制每个索引元素,其中五个参数分别是来源数组、来源起始索引、目的数组、目的起始索引、复制长度,还有个更方便的Arrays.copyOf()方法,你不用另行建立新数组,Arrays.copyOf()会帮你建立,例如:
import java.util.Arrays;
public class CopyArray {
public static void main(String[] args) {
int[] scores1={88,81,74,68,78,76,77,85,95,93};
int[] scores2=Arrays.copyOf(scores1,scores1.length);
for(int score:scores2){
System.out.printf("%3d",score);
}
System.out.println();
scores2[0]=99;
for(int score:scores1){
System.out.printf("%3d",score);
}
}
}
如果事先建立的数组长度不够,那就只好建立新数组,将原数组内容复制至新数组。
class Clothes{
String color;
char size;
Clothes(String color,char size){
this.color=color;
this.size=size;
}
}
public class ShallowCopy {
public static void main(String[] args) {
Clothes[] c1={new Clothes("red",'L'),new Clothes("blue",'M')};
Clothes[]c2=new Clothes[c1.length];
for(int i=0;i<c1.length;i++){
c2[i]=c1[i];
}
c1[0].color="yellow";
System.out.println(c2[0].color);
}
实际上循环中仅将c1每个索引处所参考的对象,也给c2每个索引来参考,并没有实际复制出Clothes对象,术语上说,这叫做复制参考。
class Clothes2{
String color;
char size;
Clothes2(String color,char size){
this.color=color;
this.size=size;
}
}
public class DeepCopy {
public static void main(String[] args) {
Clothes2[] c1={new Clothes2("red",'L'),new Clothes2("blue",'M')};
Clothes2[]c2=new Clothes2[c1.length];
for(int i=0;i<c1.length;i++){
Clothes2 c=new Clothes2(c1[i].color,c1[i].size);
c2[i]=c;
}
c1[0].color="yellow";
System.out.println(c2[0].color);
}
}
这个范例执行所谓深层复制行为,也就是实际上c1每个索引参考的对象会被复制,分别指定给c2每个索引,结果就是显示red.
4.4 字符串对象
在Java中,字符串是java.lang.String实例,用来打包字符数组。
在Java中可以使用+运算来连接字符串。使用+连接字符串会产生新的String实例,不要将+用在重复性的连接场合,像是循环中或递归时使用+连接字符串,这会因为频繁产生新对象,造成效能上的负担,但这可以用StringBuilder来改善:
public class OneTo100 {
public static void main(String[] args) {
StringBuilder builder=new StringBuilder();
for(int i=1;i<100;i++){
builder.append(i).append('+');
}
System.out.println(builder.append(100).toString());
}
}
第五章
5.1 何谓封装
封装目的主要就是隐藏对象细节,将对象当做黑箱进行操作。private也可以用在方法或构造函数声明上,私有方法或构造函数通常是类内部某个共享的演算流程,外界不用知道私有方法的存在
public class CashApp {
public static void main(String[] args) {
CashCard[] cards={
new CashCard("A001",500,0),
new CashCard("A002",300,0),
new CashCard("A003",1000,1),
new CashCard("A004",2000,2),
new CashCard("A005",3000,3)
};
for(CashCard card:cards){
System.out.printf("(%s, %d, %d)%n",card.number,card.balance,card.bonus);
}
}
}
package cc.openhome;
public class CashCard {
private String number;
private int balance;
private int bonus;
void store(int money){
if(money>0){
this.balance+=money;
if(money>=1000){
this.bonus++;
}
}
else{
System.out.println("储值是负的?你是来乱的吗?");
}
}
int getBalance(){
return balance;
}
int getBonus(){
return bonus;
}
String getNumber(){
return number;
}
}
5.2类语法细节
public权限修饰:如果没有声明权限修饰的成员,只有在相同包的类程序代码下才可以直接存取,也就是“包范围权限”。如果想在其他包的类程序代码中存取某包的类或对象成员,则该类或对象成员必须是公开成员,在java中要使用public加以声明。
关于构造函数:如果定义类时,没有撰写任何构造函数,编译程序自动加入一个无参数、内容为空的构造函数,称为默认构造函数。可以定义多个构造函数,只要参数类型或个数不同,这称为重载构造函数。
构造函数与方法重载:编译程序在处理重载方法时,会依以下顺序来处理:
1、还没有装箱动作前可符合自变量个数与类型的方法。
2、装箱动作后可符合自变量个数与类型的方法。
3、尝试有不定长度自变量并可符合自变量类型的方法。
4、找不到合适的方法,编译错误。
使用this:
package cc.openhome;
class Other{
{
System.out.println("对象初始区块");
}
Other(){
System.out.println("Other()构造函数");
}
Other(int o){
this();
System.out.println("Other(int o)构造函数");
}
}
public class ObjectInitialBlock {
public static void main(String[] args) {
new Other(1);
}
}
static类成员:如果对象数据成员被声明为final,但没有明确使用=指定值,那表示延迟对象成员值的指定,在构造函数执行流程中,一定要有对该数据成员指定值的动作,否则编译错误。被声明为static的成员,不会让个别对象拥有,而是属于类。
package cc.openhome;
import java.util.Scanner;
import static java.lang.System.in;
import static java.lang.System.out;
public class ImportStatic {
public static void main(String[] args) {
Scanner scanner=new Scanner(in);
out.print("请输入姓名:");
out.printf("%s 你好!%n",scanner.nextLine());
}
}
import static语法是为了偷懒,但别偷懒过头,要注意名称冲突问题,有些名称冲突编译程序可通过以下顺序来解析:
1、局部变量覆盖;
2、成员覆盖;
3、重载方法比较。
不定长度自变量:在JDK5之后支持不定长度自变量,为编译程序蜜糖,展开后变为数组。使用不定长度自变量时,方法上声明的不定长度参数必须是参数列最后一个,使用两个以上不定长度自变量也是不合法的。
内部类:可以在类中再定义类,这称为内部类。内部类可以定义在类区块之中;也可以使用public、protected或private声明;也可以声明为static.
传值调用:
package cc.openhome;
public class CallByValue {
public static void main(String[] args) {
Customer c1=new Customer("Justin");
some(c1);
System.out.println(c1.name);
Customer c2=new Customer("Justin");
other(c2);
System.out.println(c2.name);
}
static void some(Customer c){
c.name="John";
}
static void other(Customer c){
c=new Customer("Bill");
}
}
class Customer{
String name;
Customer(String name){
this.name=name;
}
}
教材学习中的问题和解决过程
还是有些不太清楚什么事候用printf、print、println,只知道println不仅可以输出还可以直接换行,在P85代码中,输出使用了println运行结果出现错误。
解决过程:还没有解决。
代码调试中的问题和解决过程
这两章书上的代码比较多,刚开始输入还比较细心,到后来就出现输入不细心而出现运行错误,经过细心检查改正了错误。
其他(感悟、思考等,可选)
这两章的学习内容较前几章比知识点多,而且有好多都不是很好理解,我需要花费更多的时间去练习、去理解,这两章是我学习Java以来敲代码最多的一次,多多实践练习,虽然书上的代码我不能保证百分之百我都会,但我一定会认真学习相关知识,争取自己能早日写出代码!
托管代码
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 100/100 | 1/2 | 10/15 | |
第二周 | 100/200 | 2/4 | 15/30 | |
第三周 | 300/500 | 1/5 | 30/60 |