201871010123-吴丽丽《面向对象程序设计(Java)》第四周学习总结
阅读原文时间:2023年07月13日阅读:2

201871010123-吴丽丽《面向对象程序设计(Java)》第四周学习总结

项目

内容

这个作业属于哪个课程

https://www.cnblogs.com/nwnu-daizh/

这个作业的要求在哪里

https://www.cnblogs.com/nwnu-daizh/p/11552848.html

作业的学习目标

1. 掌握类与对象的基础概念,理解类与对象的关系;

2. 掌握对象与对象变量的关系;

3. 掌握预定义类Date、LocalDate类的常用API;

4. 掌握用户自定义类的语法规则,包括实例域、静态域、构造器方法、更改器方法、访问器方法、静态方法、main方法、方法参数的定义要求;(重点、难点)

5. 掌握对象的构造方法、定义方法及使用要求;(重点);

6. 理解重载概念及用法;

掌握包的概念及用法

第一部分:总结第四章理论知识

1.类与对象的基础概念

A:什么是类?

a)类是具有相同属性和行为的一组对象的集合

b)类(class)是描述对象的模板,它定义一类对象所能拥有的数据和能完成的操作,在面向对象的程序设计中,类是构造程序的基本单元。

c)每个类由一组结构化的数据(称作实例域)和在其上的一组操作(称为方法)构成。

B:什么是对象?

a)对象是具体实体,具有明确定义的状态和行为。

b)对象的三个主要特征:

-行为(behavior):可以对对象施加什么操作(方法)?

-状态(state):当施加哪些方法时,对象如何如何响应?

-标识(identity):如何辨别具体相同行为与状态的不同对象?

2.类与对象的关系

a)类是对象,事物的描述和抽象,是具有相同属性和行为的对象集合。对象则是该类事物的实例。    

b)类是一个静态的概念,类本身不携带任何数据。当没有为类创建任何对象时,类本身不存在于内存空间中。对象是一个动态的概念。每一个对象都存在着有别于其它对象的属于自己的独特的属性和行为。对象的属性可以随着它自己的行为而发生改变。

3.类之间的关系:

a)依赖(use-a):如果一个类中的方法操作了另一个类的对象,那么这个类就依赖于另一个类。

b)聚合(has-a):类A的对象包含类B的对象

c)继承(is-a):表示一个特定类和一个一般类之间的关系。一般来说,如果类A继承了类B,那么类A不仅继承了类B的方法和状态,而且还有属于自己的方法和状态。

4.预定义类的使用

a)已学过的预定义类:Math类、math类、String类、Scanner类等,掌握练习预定义类API的技术方法。

b)要使用预定义类的方法,只需知道方法名和参数即可,无需了解它的内部实现过程。

c)使用预定义类需要在程序开始处使用import命令导入该类所在的包路径。

5.对象与对象变量

1)对象

a)在OOP中,要想使用对象,需先构造对象,并初始化对象状态,然后通过对象调用类中的办法。

b)java中,用构造器(constructor)构造并初始化对象。

c)构造器是类中一个特殊方法,该方法名与类名相同。

d)构造并初始化对象的格式:

new 构造器名(参数)

2)对象变量

a)如果要多次使用初始化的对象,可将初始化的对象放在一个对象变量中。

格式: Date birthday = new Date();

b)对象变量保存了对象后,可用对象变量引用对象。

注:对象变量不能空引用。也可以显示的将变量对象设置为null,表面这个对象变量目前没有引用任何对象。

6.用户自定义类

(1)类的定义包括两部分内容:声明和类体

(2)类体由两部分构成:

一为实体域(或成员变量)定义;二为方法定义。

(3)域的定义

a)实例域(成员变量):类定义时实例域部分所定义的变量。实例域在整个类内都有效。

b)局部变量:方法体中定义的变量和方法的参数。只在定义它的方法内有效。

(4)实例域的隐藏性

局部变量与实例域名字相同时,则实例域被隐藏,即在这个方法内暂时失效。

7.掌握用户自定义类的语法规则,包括静态域、构造器方法、更改器方法、访问器方法、静态方法、main方法、方法参数的定义要求

a)实例域:可将实例域定义为final,构建对象时必须初始化这样的域。

b)静态域:绝大多数面向对象程序设计语言中,静态域被称为类域。如果将域定义为static,每个类中只有一个这样的域。而每个对象对于所有的实例域却都有自己的一份拷贝。

c)静态方法:静态方法是一种不能向对象实时操作的方法。可以使用对象或类名调用静态方法。

d)构造器方法:构造器与类同名。构造器总是伴随着new操作符的执行被调用,而不能对一个已经存在的对象调用构造器来达到重新设置实例域的目的。

e)更改器方法:一个类中对实例域进行修改的方法,通常更改器方法名前缀为set。调用更改器方法后对象的状态会改变。

f)访问器方法:只访问对象而不修改对象的方法。

g)main方法:main方法不对任何对象进行操作。静态的main方法将执行并创建程序所需要的对象。

8.重载

多个方法有相同的名字、不同的类型、不同的参数、便产生了重载。Java允许重载任何方法,而不只是构造器方法。

9.包

1)Java允许使用包将类组织起来。借助包可以方便地组织自己的代码,并将自己的代码与别人提供的代码库分开管理。而且使用包可以确保类名的唯一性。

2)包作用域

a)类中标记为public的部分可以被任意类使用;

b)类中标记为private的部分只能在类中使用;

c)如果没有为类、方法或实例域指定访问控制修饰符public或private,这部分可以被同一包中的所有方法访问。

10.文档注释技术

a)类注释

b)方法注释

c)域注释

d)通用注释

e)包与概述注释

第二部分:实验部分

实验名称:实验三 类与对象的定义及使用

1.  实验目的:

(1) 熟悉PTA平台线上测试环境;

(2) 理解用户自定义类的定义;

(3) 掌握对象的声明;

(4) 学会使用构造函数初始化对象;

(5) 使用类属性与方法的使用掌握使用;

(6) 掌握package和import语句的用途。

2.实验步骤与内容

实验1 任务1

公民身份证号码按照GB11643—1999《公民身份证号码》国家标准编制,由18位数字组成:前6位为行政区划分代码,第7位至14位为出生日期码,第15位至17位为顺序码,第18位为校验码。从键盘输入1个身份证号,将身份证号的年月日抽取出来,按年-月-日格式输出。注意:输入使用Scanner类的nextLine()方法,以免出错。

输入样例:

34080019810819327X

输出样例:

1981-08-19

程序代码如下:

import java.util.Scanner;

public class Main {

public static void main(String\[\] args) {  
    // TODO Auto-generated method stub  
    Scanner in = new Scanner(System.in);  
    System.out.println("please input your ID:");  
    String s1 = in.nextLine();  
    String s2,s3,s4;  
    s2 = s1.substring(6, 10);  
    s3 =s1.substring(10, 12);  
    s4 = s1.substring(12, 14);  
    System.out.println(s2+"-"+s3+"-"+s4);

}

}

  程序运行如下:

实验1 任务二

studentfile.txt文件内容是某班同学的学号与姓名,利用此文件编制一个程序,将studentfile.txt文件的信息读入到内存,并提供两类查询功能:(1)输入姓名查询学号;(2)输入学号查询姓名。要求程序具有友好人机交互界面。

编程建议:

(1)从文件中读入学生信息,可以编写如下函数:

public static void StudentsFromFile(String fileName))

(2)输入姓名查找学生学号,可以编写如下函数:

public static String findStudent(String name)

(3)输入学号查找学生姓名,可以编写如下函数:

public static String findStudent(String ID)

程序代码如下:

package Package;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

public class Main {
private static Student students[];
public static void main(String[] args) {
students=new Student[];
Scanner in = new Scanner(System.in);
try {
readFile("studentfile.txt");
System.out.println("请选择操作,1按姓名,2按学号,3退出");
int i;
while ((i = in.nextInt()) != ) {
switch (i) {
case :
System.out.println("请输入姓名");
String name = in.next();
Student student = findStudentByName(name);
if (student == null) {
System.out.println("没找到");
} else {
System.out.println(student.toString());
}
System.out.println("请选择操作,1按姓名,2按学号,3退出");
break;
case :
System.out.println("请输入学号");
String id = in.next();
Student student1 = findStudentById(id);
if (student1 == null) {
System.out.println("没找到");
} else {
System.out.println(student1.toString());

                }  
                System.out.println("请选择操作,1按姓名,2按学号,3退出");  
                break;

            default:  
                System.out.println("输入有误");  
                System.out.println("请选择操作,1按姓名,2按学号,3退出");  
                break;  
            }

        }  
    } catch (IOException e) {  
        // TODO 自动生成的 catch 块  
        e.printStackTrace();  
    }finally {  
        in.close();  
    }

}

public static void readFile(String path) throws IOException {  
    FileReader reader = new FileReader(path);  
    BufferedReader br = new BufferedReader(reader);  
    String result;  
    int i=;  
    while ((result = br.readLine()) != null) {  
        Student student = new Student();  
        student.setName(result.substring());  
        student.setID(result.substring(,));  
        students\[i\]=student;  
        i++;  
    }  
    br.close();  
}

public static Student findStudentByName(String name) {  
    for (Student student : students) {  
        if (student.getName().equals(name)) {  
            return student;  
        }  
    }  
    return null;

}

public static Student findStudentById(String Id) {  
    for (Student student : students) {  
        if (student.getID().equals(Id)) {  
            return student;  
        }  
    }  
    return null;

}  

}

class Student {
private String name;
private String ID;

public String getName() {  
    return name;  
}

public void setName(String name) {  
    this.name = name;  
}

public String getID() {  
    return ID;  
}

public void setID(String iD) {  
    ID = iD;  
}

@Override  
public String toString() {  
    // TODO 自动生成的方法存根  
    return "姓名是:" + name + "学号是:" + ID;  
}  

}

程序运行结果如下:

实验2 导入第4章示例程序并测试。

测试程序1:

l 编辑、编译、调试运行程序4-2(教材104页);

l 结合程序运行结果,掌握类的定义与类对象的用法,并在程序代码中添加类与对象知识应用的注释;

l 尝试在项目中编辑两个类文件(Employee.java、 EmployeeTest.java ),编译并运行程序。

l 参考教材104页EmployeeTest.java,设计StudentTest.java,定义Student类,包含name(姓名)、sex(性别)、javascore(java成绩)三个字段,编写程序,从键盘输入学生人数,输入学生信息,并按以下表头输出学生信息表:

姓名    性别 java成绩

程序4-2代码如下:

import java.time.*; //导入java.time的包

/**
* This program tests the Employee class.
* @version 1.13 2018-04-10
* @author Cay Horstmann
*/
public class EmployeeTest
{
public static void main(String[] args)
{
// 用三个employee对象填充staff数组
Employee[] staff = new Employee[3];

  staff\[0\] = new Employee("Carl Cracker", 75000, 1987, 12, 15);  
  staff\[1\] = new Employee("Harry Hacker", 50000, 1989, 10, 1);  
  staff\[2\] = new Employee("Tony Tester", 40000, 1990, 3, 15);

  // raise everyone's salary by 5%    给每人涨5%的工资  
  for (Employee e : staff)     //进行foreach循环  
     e.raiseSalary(5);

  // print out information about all Employee objects  
  for (Employee e : staff)  
     System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay="  
        + e.getHireDay());  

}
}

class Employee
{
private String name; //实例域定义
private double salary; //实例域定义
private LocalDate hireDay; //实例域定义

public Employee(String n, double s, int year, int month, int day) //构造器的定义
{
name = n;
salary = s;
hireDay = LocalDate.of(year, month, day);
}

public String getName() //实例域name的访问器方法
{
return name;
}

public double getSalary() //实例域Salary的访问器方法
{
return salary;
}

public LocalDate getHireDay() ////实例域HireDay的访问器方法
{
return hireDay;
}

public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}

 程序运行结果如下

EmployeeTest.java

package test

public class EmployeeTest
{
public static void main(String[] args)
{
// 用三个employee对象填充staff数组
Employee[] staff = new Employee[];

   staff\[\] = new Employee("Carl Cracker", , , , );  
   staff\[\] = new Employee("Harry Hacker", , , , );  
   staff\[\] = new Employee("Tony Tester", , , , );

   // raise everyone's salary by 5%    给每人涨5%的工资  
   for (Employee e : staff)     //进行foreach循环  
      e.raiseSalary();

   // print out information about all Employee objects  
   for (Employee e : staff)  
      System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay="  
         + e.getHireDay());  
}  

}

程序运行结果如下:

Employee.java

import java.time.LocalDate;

public class Employee {

private String name;   //实例域定义  
private double salary;  //实例域定义  
private LocalDate hireDay;  //实例域定义

public Employee(String n, double s, int year, int month, int day)     //构造器的定义  
{  
   name = n;  
   salary = s;  
   hireDay = LocalDate.of(year, month, day);  
}

public String getName()    //实例域name的访问器方法  
{  
   return name;  
}

public double getSalary()  //实例域Salary的访问器方法  
{  
   return salary;  
}

public LocalDate getHireDay()  ////实例域HireDay的访问器方法  
{  
   return hireDay;  
}

public void raiseSalary(double byPercent)  
{  
   double raise = salary \* byPercent / ;  
   salary += raise;  
}  

}

程序运行结果如下

按以下表头输出学生信息表:

姓名      性别     java成绩

代码如下:

import java.util.Scanner;

public class student {
String name;
String sex;
double javascore;
public static void main(String[] args) {
System.out.println("请输入学生人数");
Scanner su = new Scanner(System.in);
int totalStudent = su.nextInt();
student[] stus= new student[totalStudent];
for(int i=;i<totalStudent;i++) {
student s =new student();
stus[i]=s;
System.out.println("请输入第+“i"+"个学生的姓名");
s.name = su.next();
System.out.println("请输入第+“i"+"个学生的性别");
s.sex = su.next();
System.out.println("请输入第+“i"+"个学生的java成绩");
s.javascore = su.nextDouble();

     }  
     printstudent(stus);  
     su.close();  
 }

 public static void printstudent(student\[\] s) {  
     System.out.println("姓名\\t性别\\tjava成绩");  
     for(int i=;i<s.length;i++) {  
         System.out.println(s\[i\].name+"\\t"+s\[i\].sex+"\\t"+s\[i\].javascore);  
      }  
 }  

}

运行结果如下:

实验2

测试程序2:

l 编辑、编译、调试运行程序4-3(教材116);

l 结合程序运行结果,理解程序代码,掌握静态域(netxtId)与静态方法(getNextId)的用法,在相关代码后添加注释;

理解Java单元(类)测试的技巧。

代码如下:

/**
* This program demonstrates static methods.
* @version 1.02 2008-04-10
* @author Cay Horstmann
*/
public class StaticTest
{
public static void main(String[] args)
{
// fill the staff array with three Employee objects (用三个employee对象填充staff数组 )
Employee[] staff = new Employee[]; //构造了一个Employee 数组,并填入三个雇员对象

   staff\[\] = new Employee("Tom", );  
   staff\[\] = new Employee("Dick", );  
   staff\[\] = new Employee("Harry", );

   // print out information about all Employee objects    (打印有关所有员工对象的信息 )  
   for (Employee e : staff)       //调用getName 方法,getId方法和getSalary方法将每个雇员的信息打印出来  
   {  
      e.setId();  
      System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="  
         + e.getSalary());  
   }

   int n = Employee.getNextId(); // calls static method    (通过类名调用静态方法 )  
   System.out.println("Next available id=" + n);  
}  

}

class Employee
{
private static int nextId = ;

private String name;     //实例域定义  
private double salary;  
private int id;

public Employee(String n, double s)     //构造器定义  
{  
   name = n;  
   salary = s;  
   id = ;  
}

public String getName()        //实例域name的访问器方法  
{  
   return name;  
}

public double getSalary()    //实例域Salary的访问器方法  
{  
   return salary;  
}

public int getId()          //实例域Id的访问方法  
{  
   return id;  
}

public void setId()  
{  
   id = nextId; // set id to next available id    (将id设置为下一个可用id )  
   nextId++;  
}

public static int getNextId()        //实例域NextId的访问方法  
{  
   return nextId; // returns static field    (返回静态字段)  
}

public static void main(String\[\] args) // unit test    (单元测试 )  
{  
   Employee e = new Employee("Harry", );  
   System.out.println(e.getName() + " " + e.getSalary());  
}  

}

运行结果如下:

实验2

测试程序3:

l 编辑、编译、调试运行程序4-4(教材121);

l 结合程序运行结果,理解程序代码,掌握Java方法参数的用法,在相关代码后添加注释;

/**
* This program demonstrates parameter passing in Java.
* @version 1.01 2018-04-10
* @author Cay Horstmann
*/
public class ParamTest
{
public static void main(String[] args)
{
/*
* Test 1: Methods can't modify numeric parameters(方法不能修改数值参数)
*/
System.out.println("Testing tripleValue:");
double percent = ;
System.out.println("Before: percent=" + percent);
tripleValue(percent); //调用方法tripleSalary
System.out.println("After: percent=" + percent);

  /\*  
   \* Test 2: Methods can change the state of object parameters (方法可以更改对象参数的状态)  
   \*/  
  System.out.println("\\nTesting tripleSalary:");  
  var harry = new Employee("Harry", );  
  System.out.println("Before: salary=" + harry.getSalary());  
  tripleSalary(harry);               //调用方法tripleSalary  
  System.out.println("After: salary=" + harry.getSalary());

  /\*  
   \* Test 3: Methods can't attach new objects to object parameters  
   \*/  
  System.out.println("\\nTesting swap:");  
  var a = new Employee("Alice", );    //定义一个类型为var的a,并进行初始化  
  var b = new Employee("Bob", );  
  System.out.println("Before: a=" + a.getName());  
  System.out.println("Before: b=" + b.getName());  
  swap(a, b);               //交换函数  
  System.out.println("After: a=" + a.getName());  
  System.out.println("After: b=" + b.getName());  

}

public static void tripleValue(double x) // doesn't work(不工作)
{
x = * x;
System.out.println("End of method: x=" + x);
}

public static void tripleSalary(Employee x) // works
{
x.raiseSalary(); //x的调用
System.out.println("End of method: salary=" + x.getSalary());
}
//x和y进行交换
public static void swap(Employee x, Employee y)
{
Employee temp = x;
x = y;
y = temp;
System.out.println("End of method: x=" + x.getName());
System.out.println("End of method: y=" + y.getName());
}
}

class Employee // simplified Employee class
{
private String name; //实例域定义
private double salary;

public Employee(String n, double s) //构造器定义
{
name = n;
salary = s;
}

public String getName() //实例域name的访问器方法
{
return name;
}

public double getSalary() ////实例域Salary的访问器方法
{
return salary;
}

public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / ;
salary += raise;
}
}

运行结果如下:

实验2

测试程序4:

l 编辑、编译、调试运行程序4-5(教材129);

l 结合程序运行结果,理解程序代码,掌握Java用户自定义类的用法,掌握对象构造方法及对象使用方法,在相关代码后添加注释。

代码如下:

import java.util.*;

/**
* This program demonstrates object construction.
* @version 1.02 2018-04-10
* @author Cay Horstmann
*/
public class ConstructorTest
{
public static void main(String[] args)
{
// fill the staff array with three Employee objects (用三个employee对象填充staff数组 )
var staff = new Employee[];

   staff\[\] = new Employee("Harry", );  
   staff\[\] = new Employee();  
   staff\[\] = new Employee();

   // print out information about all Employee objects  (打印有关所有员工对象的信息 )  
   for (Employee e : staff)    //foreach循环  
      System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="  
         + e.getSalary());  
}  

}

class Employee
{
private static int nextId; //静态域nextId

private int id;  
private String name = ""; // instance field initialization(实例字段intialization)  
private double salary;

// static initialization block  (静态intialization块)  
static  
{  
   var generator = new Random();  
   // set nextId to a random number between 0 and 9999   (将nextId设置为0到999之间的随机值)  
   nextId = generator.nextInt();  
}

// object initialization block    (对象intialization块)  
{  
   id = nextId;  
   nextId++;  
}

// three overloaded constructors   //三个重载的构造  
public Employee(String n, double s)  
{  
   name = n;  
   salary = s;  
}

public Employee(double s)  
{  
   // calls the Employee(String, double) constructor  
   this("Employee #" + nextId, s);   //this用来引用当前对象  
}

// the default constructor      //默认的构造器(本应有但没构造,所以系统自动默认了一个构造器  
public Employee()  
{  
   // name initialized to ""--see above  
   // salary not explicitly set--initialized to 0  
   // id initialized in initialization block  
}

public String getName()   //实例域name的访问器方法  
{  
   return name;  
}

public double getSalary()  //实例域Salary的访问器方法  
{  
   return salary;  
}

public int getId()    //实例域Id的访问器方法  
{  
   return id;  
}  

}

运行结果如下:

实验2

测试程序5:

l 编辑、编译、调试运行程序4-6、4-7(教材135);

l 结合程序运行结果,理解程序代码,掌握Java包的定义及用法,在相关代码后添加注释;

程序4-6代码如下:

import com.horstmann.corejava.*;
// the Employee class is defined in that package (Employees类在该包中定义)

import static java.lang.System.*; //静态导入System类

/**
* This program demonstrates the use of packages.
* @version 1.11 2004-02-19
* @author Cay Horstmann
*/
public class PackageTest
{
public static void main(String[] args)
{
// because of the import statement, we don't have to use
// com.horstmann.corejava.Employee here
var harry = new Employee("Harry Hacker", , , , );

  harry.raiseSalary();

  // because of the static import statement, we don't have to use System.out here  
  out.println("name=" + harry.getName() + ",salary=" + harry.getSalary());  

}
}

运行结果如下:

程序4-7代码如下:

package com.horstmann.corejava; //将类放入包中

// the classes in this file are part of this package (这个文件中的类就是这个包中的一部分)

import java.time.*; //java.time包的引入

// import statements come after the package statement (import语句位于package语句之后)

/**
* @version 1.11 2015-05-08
* @author Cay Horstmann
*/
public class Employee
{
private String name; //实例域定义
private double salary;
private LocalDate hireDay;

public Employee(String name, double salary, int year, int month, int day) //构造器定义
{
this.name = name; //this用来引用当前对象
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
}

public String getName() //实例域name的访问器方法
{
return name;
}

public double getSalary() //实例域Salary的访问器方法
{
return salary;
}

public LocalDate getHireDay() //实例域HireDay的访问器方法
{
return hireDay;
}

public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / ;
salary += raise;
}
}

运行结果如下:

第三部分  实验总结

本周学了第四章,通过这周的学习,我掌握了预定义类的基本使用方法,如Math类、String类、math类、Scanner类、LocalDate类等常用API;大致掌握了用户自定义类的语法规则,如实例域、静态域、构造器方法、更改器方法、访问器方法、静态方法、main方法、方法参数的定义要求等。

  但还是有些不足,概念理解不够深刻,没能够将理论知识掌握好,因此写这博客园写起来挺费劲的,在这花费了很多时间。在运行示例代码的过程中学到了相关知识,但是还没理解透,理解起来有一定的难度,在学习中还有一些漏洞和疑惑,在看翁恺老师的视频时解决了部分,但还是感觉自己有着很多的欠缺,在以后的学习中会更加努力。