201871010118-唐敬博《面向对象程序设计(Java)》第四周学习总结

博文正文开头格式:(2分)

项目

内容

这个作业属于哪个课程

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

这个作业的要求在哪里

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

作业学习目标

(1)适应老师教学方式,能按照自主学习要求完成本周理论知识学习;

(2)掌握Java Application程序结构;

(3)掌握Java语言的数据类型与变量;

(4)学会使用Java运算符构造各类表达式;

(5)掌握Java Application输入输出技术;

(6)掌握Java流程控制技术(分支、循环);(重点)

(7)掌握Math类、String类的用法。(难点)

随笔博文正文内容包括:

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

一.类

1.类体

      类使用类体来描述所抽象出的属性 行为,类声明后的一对大括号{ ....... }以及他们之间的内容称作类体

      变量的声明:依赖存储属性的值(体现对象的属性)

      方法的定义:方法可以对类中声明的变量进行操作即给出算法;

2.成员变量

      成员变量类型:整型,浮点型,字符型,逻辑类型,引用类型:数组类型,对象,接口

      成员变量的有效范围:成员变量在整个类内都有效;

 

3.对象:三个主要特性;对象的行为,对象的状态,对象标识
4. 

5.类之间的关系:依赖,聚合,继承

二.构造方法:无返回类型,方法名与类同名默认构造方法:如果类内没有定义该类的构造方法;这默认生成默认的无参的构造方法;倘若类内有定义一个或者多个构造方法这系统不默认生成无参构造方法;

  1.创建对象   格式:Class_Name    Object_name

            Class   A;

         new Class_Name:返回的是该类在堆区中开辟内存的引用;对象的引用在栈区中,对象的实体在堆区中;

  2.使用对象 对象操作自身的变量:格式:对象.变量

        对象操作自身的函数:格式:对象.函数名()

  3.对象的引用和实体   Class   A;   Class B;

               A    a  =   new    A();

               A    b=a;//注意b中存放着是a的值;b即为a的引用;

三. 用户自定义类

1.Employee类 :在源文件中,只能有一个public类,并且文件名与public类类名相同,但可以有任意数目的非公有类。

2.多个源文件的使用 :编译多个源文件的程序时,只需javac 含主方法的文件 即可,编译器会自动查找编译使用到的类。并且,若之前编译过,若java编译器发现Employee.java较之前Employee.class有更新,会再编译新版本。

3.剖析Employee类:  强烈建议将实例子域标记为private。private确保只有类自身的方法能访问该实例域。一般将方法标记为public。public意味任何类的任何方法都可调用本方法。

4.从构造器开始 :必须注意在所有方法中不要命名与实例域同名的变量,否则局部变量会屏蔽同名实例域。

                           隐式参数与显式参数 方法中,关键字this表示隐式参数。Java中,所有方法必须在类内部定义,但并不表示它们是内联方法,是否将某个方法设置为内联方法是Java虚拟机的任务。

5.封装的优点: 获得实例域的值,用get set 方法(域访问器方法/域更改器方法)好处:不要编写返回 引用可变对象 的访问器方法,要返回一个可变对象的引用,应首先对它进行克隆(clone方法)。

 

              可以改变内部实现,除了该类的方法外,不影响其它代码。更改器方法内部可以写错误检查等语句。

6.基于类的访问权限  一个方法可以访问所属类的所有对象的私有数据,而不仅限于访问隐式参数的私有特性。

7.私有方法 :可以设置一些辅助方法为private的,并且由于不会被其他类调用,所以可以随时删去。

8.final实例域 : final修饰符修饰的实例域必须在构建对象时初始化,即确保在构造器执行之后这个实例域被赋值。一般用来修饰基本类型域、或不可变类的域,否则容易造成混淆。

四.静态域与静态方法

1.静态域与实例域: 类中带有static关键字的属于静态域。每个类只有一个静态域,静态域属于类。而每个对象对于所有的实例域都有自己的一份拷贝,即每个对象都有一个自己的实力域。

2.静态常量:(1)静态变量使用的较少,静态常量使用的较多,例如public static final double PI=3.1415926535..(2)static 静态(3)final修饰的局部变量,一旦赋值,无法改变——常量。

                (4)由于每个类的对象都可以对公有域进行修改,所以最好不要将域设计为public。但将final域设为public却没问题,因为它不允许被修改。

3.静态方法: 用static修饰的方法,只能通过类名调用。

   使用的两个情景:1一个方法所有参数都是通过显式参数提供,即没有this参数。2一个方法只需要访问类的静态域。

4.静态工厂方法——除使用构造函数外另一种创建实例的方法。

  • 定义:不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为静态工厂方法(Static factory method)。Fragment fragment = MyFragment.newIntance();
  • 考虑使用静态工厂方法代替构造器

因为静态工厂方法有诸多优点,总的来说,能够增大类的提供者对自己所提供的类的控制力。

  • 有名字
  • 可以返回原类型的子类
  • 可以有多个参数相同但名称不同的工厂方法
  • 可以减少对外暴露的属性

5.main方法:(1)main方法是一个静态方法。在启动程序时还没有任何对象,静态的main方法将执行并创建程序需要的对象。

                 (2)在一个类中可以有一个main方法,是一个常用的单元测试的技巧

  •    (3)如果想要独立地测试Employee类,只需要执行java Employee;如果Employee类是一个更大型应用Application的一部分,就可以执行java Application,Employee类的main方法将永远不会执行。

五.方法参数

Java语言中,方法参数的传递方式总是按值调用(包括当对象引用作为参数时,也是按值传递,拷贝一份对象引用),方法不能修改传递给它的任何参数变量的内容。

六.对象构造

1.重载:(1)方法的签名:要完整的描述一个方法,需要指出方法名、参数类型。(2)返回类型不是方法名的一部分,不能有两个方法名、参数类型相同却返回值不同的方法

2.默认域初始化:域与局部变量的主要不同点:如果没有初始化类中的域,域会被初始化为默认值。而方法中的局部变量必须明确地初始化。

3.初始化数据域方法二:显式域初始化,会在构造器之前执行:可以在域声明中赋值。

4.初始化数据域方法三:使用初始化块,会在构造器之前执行。

八.this关键字  

1.在构造方法中使用this:this代表当前对象
2.在实例方法中使用this

this.成员变量 this.成员方法 class A{ int x; static int y; void f(){ this.x=100; A.y=10; }

注意:this不能出现在类方法中,这是因为类方法可以通过类名直接调用,这时可能还没有任何对象的创建诞生
七.包  
1.包语句 package  包名 
2.有包名的类的存储目录:package tom.jiafei
javac   tom\jiafei\源文件
3.运行有包名的主类:
java tom.jiafei.主类名

java语言不允许用户程序使用java作为包名的一部分,例如java.bird是非法的包名(发生运行异常)

八.import  this语句

  1.引入类库中 的类

import java.util.*;//导入java.util包下的所有类

果不想引入包下的类,则直接带上包名使用 java.util.Date date=new java.util.Date();
2.引入自定义包中的类

import 包名.*;//导入该包下的所有类 .* 代表所有的类 .; 代表加载应用程序当前目录下的无名包类

this关键字  1.在构造方法中使用this:this代表当前对象  2.在实例方法中使用this

                          this.成员变量 this.成员方法 class A{ int x; static int y; void f(){ this.x=100; A.y=10; }

注意:this不能出现在类方法中,这是因为类方法可以通过类名直接调用,这时可能还没有任何对象的创建诞生

九.文档注释

Java中有3种书写注释的方式
// 行注释,从开始到本行结尾。

/* ... */ 长篇注释

/** ... */ 可生成文档的注释。

1、使用javadoc工具可以由源文件产生HTML文档。

2、javadoc抽取信息范围:包,公有类与接口,公有的和受保护的域,公有的和受保护的构造器及方法。

3、每个/**... */文档注释在标记之后紧跟着自由格式文本(free-form text),标记由@开始,如:@author或@param。

4、自由格式文本中可以使用HTML修饰符,例如:用于强调的<em> ... </em>、用于设置登宽“打字机”字体的<code> ... </code>、用于强调的<strong>...</strong>以及包含图像的<img...>等。

5、类注释:必须放在import语句之后、类定义之前。(没有必要在每一行的开始都用星号)。

6、方法注释:必须放在所述方法之前,除了通用标记外,还可以使用下面的标记:

·@param这个标记将对当前方法的参数部分添加一个条目。这个描述可以占据多行,并可以使用HTML标记。一个方法的所有@param标记必须放在一起。

·@return这个标记对当前方法的返回值进行描述。这个描述可以跨越多行,可以施工HTML标记。

·@throws这个标记描述方法可能抛出有的异常。

7、域注释:只需要对共有域(通常指的是静态常量)建立文档。

8、通用注释:下面的标记可以用在类文档的注释中:

·@author这个标记产生一个“author”(作者)条目。可以使用多个@author标记,每个@author标记对应一个作者。

·@version这个标记将产生一个“version”(版本)条目。这里的文本可以是对当前版本的任何描述。

此标记可以用在所有的文档注释中:·@since这个标记将产生一个“since”(始于)条目。

十.类设计技巧

1、一定要保证数据私有

2、一定要对数据初始化

3、不要再类中使用过多的基本类型

4、不是所有的域都需要独立的域访问器和域更改器

5、将职责过多的类进行分解

6、类名和方法名要能够体现它们的职责

7、优先使用不可变的类

第二部分:实验部分

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

1.  实验目的:

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

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

(3) 掌握对象的声明;

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

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

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

 

第二部分:实验部分

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

1.  实验目的:

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

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

(3) 掌握对象的声明;

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

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

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

3. 实验步骤与内容:

实验1  任务1(10分)

公民身份证号码按照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  任务2(25分)

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)

程序代码:

import java.io.BufferedReader;

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
 
public class Main {
    // private static Student students[];
 
    private static ArrayList<Student> list;
 
    public static void main(String[] args) {
        list = new ArrayList<>();
        Scanner in new Scanner(System.in);
        try {
            readFile("studentfile.txt");
            System.out.println("请选择操作,1按姓名,2按学号,3退出");
            int i;
            while ((i = in.nextInt()) != 3) {
                switch (i) {
                case 1:
                    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 2:
                    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;
        while ((result = br.readLine()) != null) {
            Student student = new Student();
            student.setName(result.substring(13));
            student.setID(result.substring(0,12));
            list.add(student);
        }
        br.close();
    }
 
    public static Student findStudentByName(String name) {
        for (Student student : list) {
            if (student.getName().equals(name)) {
                return student;
            }
        }
        return null;
 
    }
 
    public static Student findStudentById(String Id) {
        for (Student student : list) {
            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  测试程序1(10分)
 

实验程序如下:

import 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)
   {
      // fill the staff array with three Employee objects
      Employee[] staff = new Employee[3];        //构造Employee数组,并有三个雇员对象;
 
      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%
      for (Employee e : staff)
         e.raiseSalary(5);                    //调用raiseSalary的方法提高雇员薪水15%;
 
      // 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                             //定义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);   //根据参数设置日期,参数分别为年月日;
   }                                          //构造Employee类的对象,并声明局部变量name,salary,hireday;
 
   public String getName()
   {
      return name;                            //取得name属性的值;
   }
 
   public double getSalary()
   {
      return salary;                          //取得salsry属性的值;
   }
 
   public LocalDate getHireDay()
   {
      return hireDay;                        //取得hireday属性的值;
   }
 
   public void raiseSalary(double byPercent)
   {
      double raise = salary * byPercent / 100;
      salary += raise;                       //调用方法的对象salary实例域设置为新值;
   }
}
运行结果

实验2  测试程序2(5分)

程序如下:

/**

 * 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 = new Employee[3];   //构造了一个Employee数组,并填入了三个雇员对象
 
      staff[0] = new Employee("Tom"40000);
      staff[1] = new Employee("Dick"60000);
      staff[2] = new Employee("Harry"65000);
 
      // print out information about all Employee objects
      for (Employee e : staff)
      {
         e.setId();
         System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="
            + e.getSalary());    ////调用getName方法、getId方法以及getSalary方法将每个雇员的信息打印出来
      }
 
      int n = Employee.getNextId(); // calls static method    通过类名调用这个方法,只需要访问类的静态域
      System.out.println("Next available id=" + n);  //将其输出在控制台上
   }
}
 
class Employee     //Employee类
{
   private static int nextId = 1;     //静态方法访问自身的静态域
 
   private String name;               //私有域
   private double salary;
   private int id;
 
   public Employee(String n, double s)
   {
      name = n;
      salary = s;
      id = 0;
   }
 
   public String getName()
   {
      return name;
   }
 
   public double getSalary()
   {
      return salary;
   }
 
   public int getId()
   {
      return id;
   }
 
   public void setId()
   {
      id = nextId; // set id to next available id
      nextId++;
   }
 
   public static int getNextId()
   {
      return nextId; // returns static field
   }
 
   public static void main(String[] args) // unit test
   {
      Employee e = new Employee("Harry"50000);    
      System.out.println(e.getName() + " " + e.getSalary());   //输出在控制台上
   }
}

运行结果如下:

 

 

 

实验2  测试程序3(5分)

实验程序如下:

/**

 * 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 = 10;         //采用按值调用,然后再调用以下方法
      System.out.println("Before: percent=" + percent);
      tripleValue(percent);
      System.out.println("After: percent=" + percent);
 
      /*
       * Test 2: Methods can change the state of object parameters
       */
      System.out.println("\nTesting tripleSalary:");
      Employee harry = new Employee("Harry"50000);
      System.out.println("Before: salary=" + harry.getSalary());
      tripleSalary(harry);
      System.out.println("After: salary=" + harry.getSalary());
 
      /*
       * Test 3: Methods can't attach new objects to object parameters
       */
      System.out.println("\nTesting swap:");
      Employee a = new Employee("Alice"70000);   //按引用调用实现交换两个雇员对象状态的方法,但是并没改变存储在a和b中的对象引用
      Employee b = new Employee("Bob"60000);
      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 = 3 * x;                //假定一个方法,将一个参数的值 增加到三倍,但是percent的值依旧是10
      System.out.println("End of method: x=" + x);
   }
 
   public static void tripleSalary(Employee x)
   // works,对象引用作为参数,实现一个雇员的薪水提高两倍的操作,当调用harry = new Employee(。。。);tripleSalary(harry);实现改变对象参数的方法
   {
      x.raiseSalary(200);
      System.out.println("End of method: salary=" + x.getSalary());
   }
 
   public static void swap(Employee x, Employee y)    //编写交换两个雇员对象状态的方法
   {
      Employee temp = x;     //swap方法的参数x和y被初始化为两个对象引用的拷贝。
      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()
   {
      return name;
   }
 
   public double getSalary()
   {
      return salary;
   }
 
   public void raiseSalary(double byPercent)
   {
      double raise = salary * byPercent / 100;
      salary += raise;
   }
}

运行结果如下:

 

 

/

实验2  测试程序4(5分)

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 = new Employee[3];   //构建一个Employee类数组,并定义三个雇员对象
 
      staff[0] = new Employee("Harry"40000);
      staff[1] = new Employee(60000);
      staff[2] = new Employee();
 
      // print out information about all Employee objects
      for (Employee e : staff)
         System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="
            + e.getSalary());   //调用getName方法、getId方法以及getSalary方法将每个雇员的信息打印出来
   }
}
 
class Employee     //在执行构造器之前,先执行赋值操作,调用方法对域进行初始化,使每个雇员有一个id域
{
   private static int nextId;
 
   private int id;
   private String name = ""// instance field initialization
   private double salary;
   
   // static initialization block
   static
   {
      Employee generator = new Random();
      // set nextId to a random number between 0 and 9999
      nextId = generator.nextInt(10000);
   }
 
   // object initialization block
   {
      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);
   }
 
   // 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()
   {
      return name;
   }
 
   public double getSalary()
   {
      return salary;
   }
 
   public int getId()
   {
      return id;
   }
}
 

  运行结果如下:

 

 

 

实验程序如下:

package com.horstmann.corejava;

 
// the classes in this file are part of this package 这个文件中的类就是这个包中的一部分
 
import 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.salary = salary;
      hireDay = LocalDate.of(year, month, day);//根据参数设置日期,参数分别为年月日;
   }                              //构造Employee类的对象,并声明局部变量name,salary,hireday;
 
   public String getName()
   {
      return name;               //实例域name的访问器方法
   }
 
   public double getSalary()
   {
      return salary;                      //实例域salary的访问器方法
   }
 
   public LocalDate getHireDay()
   {
      return hireDay;               //实例域hireDay的访问器方法
   }
 
   public void raiseSalary(double byPercent)
   {
      double raise = salary * byPercent / 100;
      salary += raise;                  //调用方法的对象salary实例域设置为新值;
   }
运行结果:

4. 实验总结:(10分)

 通过第四周的学习,掌握类的定义,熟悉属性、构造函数、方法的作用,掌握用类作为类型声明变量和方法返回值;理解类和对象的区别,类可以看做一个模板,我们可以根据类来创建很多的对象,而这些对象都具有我们在类中定义的方法和属性,类是抽象的,而对象是具体的。这一章主要讲解类与对象,包括面向对象程序设计的概述,使用预定义类,用户自定义类,静态域与静态方法,方法参数,对象构造等内容。Java学习已经进行到第四周,但是在代码的设计上还是没有明显的提升,在课下空余时间,我会尽力解决不会的问题,在代码的设计还是理解方面努力。通过看翁恺老师的视频讲解先把基础的内容很好的掌握。

 

posted @ 2019-09-23 21:41  tangjingbo  阅读(182)  评论(2编辑  收藏  举报