• 201771010128 王玉兰《面象对象程序设计 (Java) 》第六周学习总结


    ---恢复内容开始---

    第一部分:基础知识总结:

    1.继承

    A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况;

    B:特点:具有层次结构、子类继承父类的方法和域;

    C:优点:代码可重用、父类的域和方法可用于子类、设计应用程序变得更加简单、可以轻松定义子类。

    2.类、超类和子类

    A:Super关键字有两个用途,一是调用超类的方法(super.方法名()),二是调用超类的构造

    (super.());  继承层次:从一个超类扩展而来的类集合;继承链:在继承层次中,从某个类个类到其祖先的路径; Java不支持多继承。

    B:多态性:泛指在程序中同一个符号在不同的情况下具有不同解释的现象;

    阻止继承:final类和方法:不允许继承的类成为Final类,在类的定义中用修饰符加以说明;

    类中的方法可定义子类,这时不能覆盖方法; String类是final类的一个例子。

    C;抽象类:包含一个或多个抽象方法的类本身必须被声明为抽象类; 抽象方法充当着占位的角色,他们的具体实现在子类中 ; 抽象不能被实例化,即不能创建对象,只能产生子类。

    D:访问修饰符:private:只有该类可以访问,public:该类或非该类均可访问,protected:该类及其子类可以访问,同一个包中的类也可以访问。(注:不写访问修饰符时默认为friendly)

    3.Object:所有类的超类

    A:Object是Java中所有类的祖先;

    B:可以使用类型为Object的变量指向任意类型的对象;

    C:Object类中的equals方法用于测试某个对象是否另一个对象也相等;

    D:定义类中的equals方法时,可调用超类的equals方法(super.equals)

    E:如果需要检测连个对象状态的相等性,就需要在新类定义中需要覆盖equals方法;

    F:Object类中的HashCode方法导出某个对象的散列码,两个相等对象的散列码相等;

    G:Object类中的toString方法返回一个代表该对象域值的字符串;

    H:定义子类的toString方法时,可先调用超类的toString方法,super.toString()。

    4.泛型数组列表

    A:Arraylist<T>=new Arraylist<T>

    B:Arrarylist的构造器:a:添加新元素,b:统计个数,c:调整大小,d:访问,e:增加与删除。

    5.对象包装器与自动打包

    A:包装器:所有基本数据类型都有着对应的预定义类;

    B:对象包装器类不可变的,它还是final类,因此不能定义它们的子类;

    C:打包和拆包是编译器认可的。

    6.参数数量可变的方法

    A:定义:可用可变的参数数量调用的方法

    B:用户可以自己定义可变参数的方法,并将参数指定为任意类型,甚至是基本类型。

    7枚举类

    A:声明枚举类  public enum Grade{A,B,C,D,E};

    B:它包括一个关键字enum,一个新枚举类型的名字Grade以及Grade定义的一组值,这里的值即非整型,又非字符型。

    8.继承设计的技巧

    A:将公共操作和域放在超类;

    B:不要使用受保护的域;

    C:使用继承实现“is-a”关系;

    D:除非所有继承的方法都有意义,否则就不要使用继承;

    E:在覆盖方法时,不要改变预期的行为;

    F:使用多态,而非类型信息;

    G:不要过多地使用反射。

    第二部分:实验部分

    实验目的与要求

    (1)  理解继承的定义;

    (2)  掌握子类的定义要求;

    (3)  掌握多态性的概念及用法;

    (4)  掌握抽象类的定义及用途;

    (5)  掌握类中4个成员访问权限修饰符的用途;

    (6)  掌握抽象类的定义方法及用途;

    (7)  掌握Object类的用途及常用API;

    (8)  掌握Arraylist类的定义方法及用法;

    (9)  掌握枚举类定义方法及用途。

    1. 实验内容和步骤

    实验1:导入第五章示例程序,测试并代码注释。

    测试程序1:

    *在eclipseIDE中编辑、调试、运行程序5-1(教材152页-153页);

    *掌握子类的用法及定义;

    *结合程序运行结果,理解并总结00风格程序构造特点,理解Employee和Manager类的关系子类的用途,并在代码中添加注释;

    5-1    Manager.Test.Java

    /**
    * This program demonstrates inheritance.
    * @version 1.21 2004-02-21
    * @author Cay Horstmann
    */
    public class ManagerTest
    {
    public static void main(String[] args)//程序入口
    {
    //构造了三个雇员对象
    var boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    boss.setBonus(5000);

    var staff = new Employee[3];

    //用经理和雇员对象填充员工工作组

    staff[0] = boss;//父类可引用子类对象
    staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
    staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);

    //输出所有员工对象的信息
    for (Employee e : staff)
    System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
    }
    }

     5-2 Employee.Java

    import java.time.*;

    public class Employee
    {
    private String name;//private表示私有属性,只能访问类内
    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);//LocateDate 类封装了实例域来维护所设置的时间
    }

    public String getName()
    {
    return name;
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

    public void raiseSalary(double byPercent)//调用了getName、getSalary、getHireDay方法
    {
    double raise = salary * byPercent / 100;
    salary += raise;
    }
    }

    5-3 Manager.Java


    public class Manager extends Employee
    {
    private double bonus;//定义了私有 的

    /**
    * @param name the employee's name
    * @param salary the salary
    * @param year the hire year
    * @param month the hire month
    * @param day the hire day
    */
    public Manager(String name, double salary, int year, int month, int day)
    {
    super(name, salary, year, month, day);//由于子类的构造器不能直接访问访问超类的私有域,必须调用超类的构造器,而且必须是第一条语句。
    bonus = 0;
    }

    public double getSalary()
    {
    double baseSalary = super.getSalary();//使用公有接口
    return baseSalary + bonus;
    }

    public void setBonus(double b)
    {
    bonus = b;
    }
    }

     程序运行结果:

    测试程序2:

    *编辑、编译、调试运行教材PersonTest程序(教材163-165);

    *掌握超类的定义及其使用要求;

    *掌握利用超类扩展子类的要求;

    *在程序相关代码处添加新知识的注释;

    5-4 Person.Test.Java


    /**
    * This program demonstrates abstract classes.
    * @version 1.01 2004-02-21
    * @author Cay Horstmann
    */
    public class PersonTest
    {
    public static void main(String[] args)
    {
    var people = new Person[2];

    // 用学生和雇员对象填充人物数组
    people[0] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
    people[1] = new Student("Maria Morris", "computer science");

    // 打印所有人对象的名称和描述
    for (Person p : people)
    System.out.println(p.getName() + ", " + p.getDescription());
    }
    }

    5-5   Person.Java

    public abstract class Person
    {
    public abstract String getDescription();
    private String name;

    public Person(String name)
    {
    this.name = name;//this.name只访问当前内容name的属性
    }

    public String getName()
    {
    return name;//返回名字
    }
    }

    5-6 Employee.Java

    import java.time.*;

    public class Employee extends Person
    {
    private double salary;//定义了工资和入职时间是私有
    private LocalDate hireDay;

    public Employee(String name, double salary, int year, int month, int day)
    {
    super(name);//超类name
    this.salary = salary;//this.salary表示当前访问的是工资的属性
    hireDay = LocalDate.of(year, month, day);//访问当前的年月日
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

    public String getDescription()
    {
    return String.format("an employee with a salary of $%.2f", salary);
    }

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

    程序运行结果:

    测试程序3:

    *编辑、编译、调试运行教材5-8、5-9、5-10,结合程序运行结果理解程序(教材174页-177页);

    *掌握Object类的定义及用法;

    *在程序相关代码处添加新知识的注释。

    5-8 Equals.Test.Java

    /**
    * This program demonstrates the equals method.
    * @version 1.12 2012-01-26
    * @author Cay Horstmann
    */
    public class EqualsTest
    {
    public static void main(String[] args)
    {
    var alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
    var alice2 = alice1;
    var alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
    var bob = new Employee("Bob Brandson", 50000, 1989, 10, 1);

    System.out.println("alice1 == alice2: " + (alice1 == alice2));

    System.out.println("alice1 == alice3: " + (alice1 == alice3));

    System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));

    System.out.println("alice1.equals(bob): " + alice1.equals(bob));

    System.out.println("bob.toString(): " + bob);

    var carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    var boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    boss.setBonus(5000);
    System.out.println("boss.toString(): " + boss);
    System.out.println("carl.equals(boss): " + carl.equals(boss));
    System.out.println("alice1.hashCode(): " + alice1.hashCode());
    System.out.println("alice3.hashCode(): " + alice3.hashCode());
    System.out.println("bob.hashCode(): " + bob.hashCode());
    System.out.println("carl.hashCode(): " + carl.hashCode());
    }
    }

    5-9 Employee.Java

    import java.time.*;
    import java.util.Objects;

    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);
    }

    public String getName()
    {
    return name;
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

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

    public boolean equals(Object otherObject)
    {
    // 快速检查对象是否相同,则返回flase
    if (this == otherObject) return true;

    // 如果显示参数为空
    if (otherObject == null) return false;

    // getClass()方法是对象的类,这里就是如果两个对象的类不一样,那么就不相等
    if (getClass() != otherObject.getClass()) return false;

    // 现在我们知道另一个对象是非空雇员
    var other = (Employee) otherObject;

    // 测试字段是否具有相同的值
    return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    }

    public int hashCode()
    {
    return Objects.hash(name, salary, hireDay);
    }

    public String toString()
    {
    return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay
    + "]";
    }
    }

    5-10   Maganer.Java

    public class Manager extends Employee
    {
    private double bonus;

    public Manager(String name, double salary, int year, int month, int day)
    {
    super(name, salary, year, month, day);
    bonus = 0;
    }

    public double getSalary()
    {
    double baseSalary = super.getSalary();
    return baseSalary + bonus;
    }

    public void setBonus(double bonus)
    {
    this.bonus = bonus;
    }

    public boolean equals(Object otherObject)
    {
    if (!super.equals(otherObject)) return false;
    var other = (Manager) otherObject;
    //检查这个和其他属于同一个类
    return bonus == other.bonus;
    }

    public int hashCode()
    {
    return java.util.Objects.hash(super.hashCode(), bonus);
    }

    public String toString()
    {
    return super.toString() + "[bonus=" + bonus + "]";
    }
    }

    程序运行结果:

     

    测试程序4:

    *在eclipseIDE中编辑、调试、运行程序5-11(教材182页),结合程序运行结果理解程序;

    *掌握Arraylist类的定义及用法;

    *在程序相关代码处添加新知识的注释。

    5-11 ArrayListTest.Java

    import java.util.*;

    /**
    * This program demonstrates the ArrayList class.
    * @version 1.11 2012-01-26
    * @author Cay Horstmann
    */
    public class ArrayListTest
    {
    public static void main(String[] args)
    {
    // 用三个雇员对象填充工作人员数组列表
    var staff = new ArrayList<Employee>();

    staff.add(new Employee("Carl Cracker", 75000, 1987, 12, 15));
    staff.add(new Employee("Harry Hacker", 50000, 1989, 10, 1));
    staff.add(new Employee("Tony Tester", 40000, 1990, 3, 15));

    // 把每个人的薪水提高5%
    for (Employee e : staff)
    e.raiseSalary(5);

    //打印所有员工对象的信息
    for (Employee e : staff)
    System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay="
    + e.getHireDay());
    }
    }

          Employee.Java

    import java.time.*;

    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);
    }

    public String getName()
    {
    return name;
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

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

    程序运行结果:

    测试程序5:

    *编辑、编译、调试运行程序5-12(教材189页),结合程序运行结果理解程序;

    *掌握枚举类的定义及用法;

    *在程序相关代码处添加新知识的注释。

    5-12   EnumTest.Java

    import java.util.*;

    /**
    * This program demonstrates enumerated types.
    * @version 1.0 2004-05-24
    * @author Cay Horstmann
    */
    public class EnumTest
    {
    public static void main(String[] args)//程序入口
    {
    var in = new Scanner(System.in);//构造一个Scanner类
    System.out.print("Enter a size: (SMALL, MEDIUM, LARGE, EXTRA_LARGE) ");
    String input = in.next().toUpperCase();
    Size size = Enum.valueOf(Size.class, input);
    System.out.println("size=" + size);
    System.out.println("abbreviation=" + size.getAbbreviation());
    if (size == Size.EXTRA_LARGE)
    System.out.println("Good job--you paid attention to the _.");
    }
    }

    enum Size
    {
    SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");

    private Size(String abbreviation) { this.abbreviation = abbreviation; }
    public String getAbbreviation() { return abbreviation; }

    private String abbreviation;
    }

    程序运行结果:

    实验2 编程练习1

    *定义抽象类Shape:

    *属性:不可变常量double PI,值为3.14;

    *方法:public double getPerimeter();public double getArea().

    *让Rectangle与Circle继承自Shape类;

    *编写double sumAllArea方法输出形状数组中的面积和double sumAllPerimeter方法输出形状数组中的周长和。

    Main()方法中

    1)       输入整型值n,然后建立n个不同的形状。如果输入rect,则在输入长和宽。如果输入cir,再输入半径。

    2)       然后输出所有形状的周长之和,面积之和。并将所有形状信息以样例的格式输出。

    思考sumAllArea和sum Allperimeter方法放在哪个类中更合适?

    输入样例:

    3

    rect

    1 1

    rect

    2 2

    输出样例:

    18.28

    8.14

    [Rectangle [width=1, length=1], Rectangle [width=2, length=2], Circle [radius=1]]

    class Rectangle,class Shape

    class Rectangle,class Shape

    class Circle,class Shape

    代码:

    import java.util.Scanner;

    public class shape {//抽象类不能构造方法

    double PI =3.14;
    double getPerimeter() {
    return 0;
    } //求周长
    double getArea() {
    return 0;

    public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int n = in.nextInt();
    System.out.println(" ");
    String rect="rect";
    String cir="cir";
    shape[] A= new shape[n];

    for(int i=0;i<n;i++){
    String s=in.next();
    if(s.equals(rect)) {

    int length = in.nextInt();
    int width = in.nextInt();
    A[i]=new Rectangle(width,length);


    }

    if (s.equals(cir)) {

    int radius = in.nextInt();
    A[i]=new Circle(radius);



    }
    }

    shape c=new shape();


    System.out.println( c.sumAllPerimeter(A));
    System.out.println(c.sumAllArea(A));

    for(int i=0;i<n;i++)
    {
    System.out.println(A[i]);

    }

    for(shape s:A) {
    System.out.println(s.getClass()+","+s.getClass().getSuperclass());

    }


    }

    public double sumAllArea(shape B[])
    {
    double sum=0;
    for(int i=0;i<B.length;i++)
    sum+= B[i].getArea();
    return sum;
    }
    public double sumAllPerimeter(shape B[])
    {
    double sum=0;
    for(int i=0;i<B.length;i++)
    sum+= B[i].getPerimeter();
    return sum;
    }
    }

     

    public class Rectangle extends shape{
    private int length;
    private int width;
    public Rectangle(int length, int width) {//这地方的参数只是形参可以不和父类的实参相同
    this.length = length;
    this.width = width;
    }
    //继承父类
    public double getPerimeter() {//此时不能用abstract
    return 2*(length+width);
    }
    double getArea(){
    return length*width; //调用父类求面积的方法
    }
    public String toString()
    {
    return getClass().getName() + "[ width=" + width + "]"+ "[length=" + length + "]";
    }
    }

    public class Circle extends shape{
    private int radius;

    public Circle(int r) {
    this.radius= r;
    }
    //继承父类
    double getPerimeter(){ //调用父类求周长的方法
    return 2*PI*radius;
    }
    double getArea(){
    return PI*radius*radius; //调用父类求面积的方法
    }
    public String toString()
    {
    return getClass().getName() + "[radius=" + radius + "]";
    }
    }

    程序运行结果:

     

     

    实验3:编程练习2

    编制一个程序,将身份证号.txt中的信息读入到内存中,输入一个身份证号或姓名,询显示对象的姓名、身份证号、年龄、性别和出生地。

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

    public class Demo {
    private static ArrayList<Student>studentlist = null;
    public static void main(String args[]) {

    studentlist = new ArrayList<>();
    Scanner scanner = new Scanner(System.in);
    File file = new File("D:\sfz/身份证号.txt" );
    BufferedReader reader = null;
    try {
    reader = new BufferedReader(new FileReader(file));

    String temp = null;
    while ((temp = reader.readLine()) != null) {
    Scanner linescanner = new Scanner(temp);
    linescanner.useDelimiter(" ");
    String name = linescanner.next();
    String number = linescanner.next();
    String sex = linescanner.next();
    String age = linescanner.next();
    String province =linescanner.nextLine();

    Student student = new Student();
    student.setName(name);
    student.setnumber(number);
    student.setsex(sex);
    student.setage(age);
    student.setprovince(province);
    studentlist.add(student);

    }

    reader.close();
    } catch (IOException e) { //读错
    e.printStackTrace();
    }


    int status=1;
    while (status!=0)
    {

    System.out.println("1:通过姓名查询");
    System.out.println("2:通过身份证号查询");
    System.out.println("0:退出");

    status = scanner.nextInt();
    switch (status) {

    case 1:
    System.out.println("请输入姓名:");
    String scanner1 = scanner.next();

    int nameint = findStudentByName(scanner1);
    if(nameint != -1) {
    System.out.println("查找信息为:身份证号:"
    + studentlist.get(nameint).getnumber() + " 姓名:"
    + studentlist.get(nameint).getName() +" 性别:"
    +studentlist.get(nameint).getsex() +" 年龄:"
    +studentlist.get(nameint).getage()+" 地址:"
    +studentlist.get(nameint).getprovince()
    );


    } break;
    case 2:
    System.out.println("请输入身份证号:");

    String studentid = scanner.next();
    int id = findStudentById(studentid);
    if (id != -1) {
    System.out.println("查找信息为:身份证号:"
    + studentlist.get(id ).getnumber() + " 姓名:"
    + studentlist.get(id ).getName() +" 性别:"
    +studentlist.get(id ).getsex() +" 年龄:"
    +studentlist.get(id ).getage()+" 地址:"
    +studentlist.get(id ).getprovince()
    );


    }break;

    case 0:
    status = 0;
    System.out.println("程序已退出!");
    break;
    default:
    System.out.println("输入错误");
    }
    }
    }

    public static int findStudentByName(String name) {
    int flag = -1;
    int a[];
    for (int i = 0; i < studentlist.size(); i++) {
    if (studentlist.get(i).getName().equals(name)) {
    flag= i;
    }
    }
    return flag;
    }


    public static int findStudentById(String id) {
    int flag = -1;

    for (int i = 0; i < studentlist.size(); i++) {
    if (studentlist.get(i).getnumber().equals(id)) {
    flag = i;
    }
    }
    return flag;

    }
    }

    public class Student {
    private String name;
    private String number ;
    private String sex ;
    private String age;
    private String province;


    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getnumber() {
    return number;
    }
    public void setnumber(String number) {
    this.number = number;
    }
    public String getsex() {
    return sex ;
    }
    public void setsex(String sex ) {
    this.sex =sex ;
    }
    public String getage() {
    return age;
    }
    public void setage(String age ) {
    this.age=age ;
    }
    public String getprovince() {
    return province;
    }
    public void setprovince(String province) {
    this.province=province ;
    }
    }
    /*public void setStudentId(String string) {
    // TODO Auto-generated method stub

    }
    public int getStudentId() {
    // TODO Auto-generated method stub
    return 0;
    }


    }*/

    运行结果:

    实验总结:

          这一周学习第五章知识,学习了继承的相关概念和基本知识,用父类对象可引用子类对象,继承是Java程序设计中的一项核心技术,也是面向对象特征之一,具有层次结构,子类继承父类的域和方法;此外还了解了超类super,知道子类的构造器不能直接访问超类的私有域,必须调用超类构造器的用法,在Java中对象变量是多态的以及抽象类的使用。此次实验由于时间原因,基本都是自主学习,通过课件和课本相结合的方法,在没有老师的帮助指导下,遇到问题都是首先考虑,即便很抽象,比如Equals方法里的知识特别模糊,在完成了所有的测试实验后,下面的两个编程程序,不由自主的停了下来,很愧疚不能完整写下代码,不能达到老师的要求,遇到了好多问题。在接下,我要好好把握时间了,不能抱有抱怨,脚踏实地,更重要的是信息,因为不会才要学

    ---恢复内容开始---

    第一部分:基础知识总结:

    1.继承

    A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况;

    B:特点:具有层次结构、子类继承父类的方法和域;

    C:优点:代码可重用、父类的域和方法可用于子类、设计应用程序变得更加简单、可以轻松定义子类。

    2.类、超类和子类

    A:Super关键字有两个用途,一是调用超类的方法(super.方法名()),二是调用超类的构造

    (super.());  继承层次:从一个超类扩展而来的类集合;继承链:在继承层次中,从某个类个类到其祖先的路径; Java不支持多继承。

    B:多态性:泛指在程序中同一个符号在不同的情况下具有不同解释的现象;

    阻止继承:final类和方法:不允许继承的类成为Final类,在类的定义中用修饰符加以说明;

    类中的方法可定义子类,这时不能覆盖方法; String类是final类的一个例子。

    C;抽象类:包含一个或多个抽象方法的类本身必须被声明为抽象类; 抽象方法充当着占位的角色,他们的具体实现在子类中 ; 抽象不能被实例化,即不能创建对象,只能产生子类。

    D:访问修饰符:private:只有该类可以访问,public:该类或非该类均可访问,protected:该类及其子类可以访问,同一个包中的类也可以访问。(注:不写访问修饰符时默认为friendly)

    3.Object:所有类的超类

    A:Object是Java中所有类的祖先;

    B:可以使用类型为Object的变量指向任意类型的对象;

    C:Object类中的equals方法用于测试某个对象是否另一个对象也相等;

    D:定义类中的equals方法时,可调用超类的equals方法(super.equals)

    E:如果需要检测连个对象状态的相等性,就需要在新类定义中需要覆盖equals方法;

    F:Object类中的HashCode方法导出某个对象的散列码,两个相等对象的散列码相等;

    G:Object类中的toString方法返回一个代表该对象域值的字符串;

    H:定义子类的toString方法时,可先调用超类的toString方法,super.toString()。

    4.泛型数组列表

    A:Arraylist<T>=new Arraylist<T>

    B:Arrarylist的构造器:a:添加新元素,b:统计个数,c:调整大小,d:访问,e:增加与删除。

    5.对象包装器与自动打包

    A:包装器:所有基本数据类型都有着对应的预定义类;

    B:对象包装器类不可变的,它还是final类,因此不能定义它们的子类;

    C:打包和拆包是编译器认可的。

    6.参数数量可变的方法

    A:定义:可用可变的参数数量调用的方法

    B:用户可以自己定义可变参数的方法,并将参数指定为任意类型,甚至是基本类型。

    7枚举类

    A:声明枚举类  public enum Grade{A,B,C,D,E};

    B:它包括一个关键字enum,一个新枚举类型的名字Grade以及Grade定义的一组值,这里的值即非整型,又非字符型。

    8.继承设计的技巧

    A:将公共操作和域放在超类;

    B:不要使用受保护的域;

    C:使用继承实现“is-a”关系;

    D:除非所有继承的方法都有意义,否则就不要使用继承;

    E:在覆盖方法时,不要改变预期的行为;

    F:使用多态,而非类型信息;

    G:不要过多地使用反射。

    第二部分:实验部分

    实验目的与要求

    (1)  理解继承的定义;

    (2)  掌握子类的定义要求;

    (3)  掌握多态性的概念及用法;

    (4)  掌握抽象类的定义及用途;

    (5)  掌握类中4个成员访问权限修饰符的用途;

    (6)  掌握抽象类的定义方法及用途;

    (7)  掌握Object类的用途及常用API;

    (8)  掌握Arraylist类的定义方法及用法;

    (9)  掌握枚举类定义方法及用途。

    1. 实验内容和步骤

    实验1:导入第五章示例程序,测试并代码注释。

    测试程序1:

    *在eclipseIDE中编辑、调试、运行程序5-1(教材152页-153页);

    *掌握子类的用法及定义;

    *结合程序运行结果,理解并总结00风格程序构造特点,理解Employee和Manager类的关系子类的用途,并在代码中添加注释;

    5-1    Manager.Test.Java

    /**
    * This program demonstrates inheritance.
    * @version 1.21 2004-02-21
    * @author Cay Horstmann
    */
    public class ManagerTest
    {
    public static void main(String[] args)//程序入口
    {
    //构造了三个雇员对象
    var boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    boss.setBonus(5000);

    var staff = new Employee[3];

    //用经理和雇员对象填充员工工作组

    staff[0] = boss;//父类可引用子类对象
    staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
    staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);

    //输出所有员工对象的信息
    for (Employee e : staff)
    System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
    }
    }

     5-2 Employee.Java

    import java.time.*;

    public class Employee
    {
    private String name;//private表示私有属性,只能访问类内
    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);//LocateDate 类封装了实例域来维护所设置的时间
    }

    public String getName()
    {
    return name;
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

    public void raiseSalary(double byPercent)//调用了getName、getSalary、getHireDay方法
    {
    double raise = salary * byPercent / 100;
    salary += raise;
    }
    }

    5-3 Manager.Java


    public class Manager extends Employee
    {
    private double bonus;//定义了私有 的

    /**
    * @param name the employee's name
    * @param salary the salary
    * @param year the hire year
    * @param month the hire month
    * @param day the hire day
    */
    public Manager(String name, double salary, int year, int month, int day)
    {
    super(name, salary, year, month, day);//由于子类的构造器不能直接访问访问超类的私有域,必须调用超类的构造器,而且必须是第一条语句。
    bonus = 0;
    }

    public double getSalary()
    {
    double baseSalary = super.getSalary();//使用公有接口
    return baseSalary + bonus;
    }

    public void setBonus(double b)
    {
    bonus = b;
    }
    }

     程序运行结果:

    测试程序2:

    *编辑、编译、调试运行教材PersonTest程序(教材163-165);

    *掌握超类的定义及其使用要求;

    *掌握利用超类扩展子类的要求;

    *在程序相关代码处添加新知识的注释;

    5-4 Person.Test.Java


    /**
    * This program demonstrates abstract classes.
    * @version 1.01 2004-02-21
    * @author Cay Horstmann
    */
    public class PersonTest
    {
    public static void main(String[] args)
    {
    var people = new Person[2];

    // 用学生和雇员对象填充人物数组
    people[0] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
    people[1] = new Student("Maria Morris", "computer science");

    // 打印所有人对象的名称和描述
    for (Person p : people)
    System.out.println(p.getName() + ", " + p.getDescription());
    }
    }

    5-5   Person.Java

    public abstract class Person
    {
    public abstract String getDescription();
    private String name;

    public Person(String name)
    {
    this.name = name;//this.name只访问当前内容name的属性
    }

    public String getName()
    {
    return name;//返回名字
    }
    }

    5-6 Employee.Java

    import java.time.*;

    public class Employee extends Person
    {
    private double salary;//定义了工资和入职时间是私有
    private LocalDate hireDay;

    public Employee(String name, double salary, int year, int month, int day)
    {
    super(name);//超类name
    this.salary = salary;//this.salary表示当前访问的是工资的属性
    hireDay = LocalDate.of(year, month, day);//访问当前的年月日
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

    public String getDescription()
    {
    return String.format("an employee with a salary of $%.2f", salary);
    }

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

    程序运行结果:

    测试程序3:

    *编辑、编译、调试运行教材5-8、5-9、5-10,结合程序运行结果理解程序(教材174页-177页);

    *掌握Object类的定义及用法;

    *在程序相关代码处添加新知识的注释。

    5-8 Equals.Test.Java

    /**
    * This program demonstrates the equals method.
    * @version 1.12 2012-01-26
    * @author Cay Horstmann
    */
    public class EqualsTest
    {
    public static void main(String[] args)
    {
    var alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
    var alice2 = alice1;
    var alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
    var bob = new Employee("Bob Brandson", 50000, 1989, 10, 1);

    System.out.println("alice1 == alice2: " + (alice1 == alice2));

    System.out.println("alice1 == alice3: " + (alice1 == alice3));

    System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));

    System.out.println("alice1.equals(bob): " + alice1.equals(bob));

    System.out.println("bob.toString(): " + bob);

    var carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    var boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    boss.setBonus(5000);
    System.out.println("boss.toString(): " + boss);
    System.out.println("carl.equals(boss): " + carl.equals(boss));
    System.out.println("alice1.hashCode(): " + alice1.hashCode());
    System.out.println("alice3.hashCode(): " + alice3.hashCode());
    System.out.println("bob.hashCode(): " + bob.hashCode());
    System.out.println("carl.hashCode(): " + carl.hashCode());
    }
    }

    5-9 Employee.Java

    import java.time.*;
    import java.util.Objects;

    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);
    }

    public String getName()
    {
    return name;
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

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

    public boolean equals(Object otherObject)
    {
    // 快速检查对象是否相同,则返回flase
    if (this == otherObject) return true;

    // 如果显示参数为空
    if (otherObject == null) return false;

    // getClass()方法是对象的类,这里就是如果两个对象的类不一样,那么就不相等
    if (getClass() != otherObject.getClass()) return false;

    // 现在我们知道另一个对象是非空雇员
    var other = (Employee) otherObject;

    // 测试字段是否具有相同的值
    return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    }

    public int hashCode()
    {
    return Objects.hash(name, salary, hireDay);
    }

    public String toString()
    {
    return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay
    + "]";
    }
    }

    5-10   Maganer.Java

    public class Manager extends Employee
    {
    private double bonus;

    public Manager(String name, double salary, int year, int month, int day)
    {
    super(name, salary, year, month, day);
    bonus = 0;
    }

    public double getSalary()
    {
    double baseSalary = super.getSalary();
    return baseSalary + bonus;
    }

    public void setBonus(double bonus)
    {
    this.bonus = bonus;
    }

    public boolean equals(Object otherObject)
    {
    if (!super.equals(otherObject)) return false;
    var other = (Manager) otherObject;
    //检查这个和其他属于同一个类
    return bonus == other.bonus;
    }

    public int hashCode()
    {
    return java.util.Objects.hash(super.hashCode(), bonus);
    }

    public String toString()
    {
    return super.toString() + "[bonus=" + bonus + "]";
    }
    }

    程序运行结果:

     

    测试程序4:

    *在eclipseIDE中编辑、调试、运行程序5-11(教材182页),结合程序运行结果理解程序;

    *掌握Arraylist类的定义及用法;

    *在程序相关代码处添加新知识的注释。

    5-11 ArrayListTest.Java

    import java.util.*;

    /**
    * This program demonstrates the ArrayList class.
    * @version 1.11 2012-01-26
    * @author Cay Horstmann
    */
    public class ArrayListTest
    {
    public static void main(String[] args)
    {
    // 用三个雇员对象填充工作人员数组列表
    var staff = new ArrayList<Employee>();

    staff.add(new Employee("Carl Cracker", 75000, 1987, 12, 15));
    staff.add(new Employee("Harry Hacker", 50000, 1989, 10, 1));
    staff.add(new Employee("Tony Tester", 40000, 1990, 3, 15));

    // 把每个人的薪水提高5%
    for (Employee e : staff)
    e.raiseSalary(5);

    //打印所有员工对象的信息
    for (Employee e : staff)
    System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay="
    + e.getHireDay());
    }
    }

          Employee.Java

    import java.time.*;

    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);
    }

    public String getName()
    {
    return name;
    }

    public double getSalary()
    {
    return salary;
    }

    public LocalDate getHireDay()
    {
    return hireDay;
    }

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

    程序运行结果:

    测试程序5:

    *编辑、编译、调试运行程序5-12(教材189页),结合程序运行结果理解程序;

    *掌握枚举类的定义及用法;

    *在程序相关代码处添加新知识的注释。

    5-12   EnumTest.Java

    import java.util.*;

    /**
    * This program demonstrates enumerated types.
    * @version 1.0 2004-05-24
    * @author Cay Horstmann
    */
    public class EnumTest
    {
    public static void main(String[] args)//程序入口
    {
    var in = new Scanner(System.in);//构造一个Scanner类
    System.out.print("Enter a size: (SMALL, MEDIUM, LARGE, EXTRA_LARGE) ");
    String input = in.next().toUpperCase();
    Size size = Enum.valueOf(Size.class, input);
    System.out.println("size=" + size);
    System.out.println("abbreviation=" + size.getAbbreviation());
    if (size == Size.EXTRA_LARGE)
    System.out.println("Good job--you paid attention to the _.");
    }
    }

    enum Size
    {
    SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");

    private Size(String abbreviation) { this.abbreviation = abbreviation; }
    public String getAbbreviation() { return abbreviation; }

    private String abbreviation;
    }

    程序运行结果:

    实验2 编程练习1

    *定义抽象类Shape:

    *属性:不可变常量double PI,值为3.14;

    *方法:public double getPerimeter();public double getArea().

    *让Rectangle与Circle继承自Shape类;

    *编写double sumAllArea方法输出形状数组中的面积和double sumAllPerimeter方法输出形状数组中的周长和。

    Main()方法中

    1)       输入整型值n,然后建立n个不同的形状。如果输入rect,则在输入长和宽。如果输入cir,再输入半径。

    2)       然后输出所有形状的周长之和,面积之和。并将所有形状信息以样例的格式输出。

    思考sumAllArea和sum Allperimeter方法放在哪个类中更合适?

    输入样例:

    3

    rect

    1 1

    rect

    2 2

    输出样例:

    18.28

    8.14

    [Rectangle [width=1, length=1], Rectangle [width=2, length=2], Circle [radius=1]]

    class Rectangle,class Shape

    class Rectangle,class Shape

    class Circle,class Shape

    代码:

    import java.util.Scanner;

    public class shape {//抽象类不能构造方法

    double PI =3.14;
    double getPerimeter() {
    return 0;
    } //求周长
    double getArea() {
    return 0;

    public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int n = in.nextInt();
    System.out.println(" ");
    String rect="rect";
    String cir="cir";
    shape[] A= new shape[n];

    for(int i=0;i<n;i++){
    String s=in.next();
    if(s.equals(rect)) {

    int length = in.nextInt();
    int width = in.nextInt();
    A[i]=new Rectangle(width,length);


    }

    if (s.equals(cir)) {

    int radius = in.nextInt();
    A[i]=new Circle(radius);



    }
    }

    shape c=new shape();


    System.out.println( c.sumAllPerimeter(A));
    System.out.println(c.sumAllArea(A));

    for(int i=0;i<n;i++)
    {
    System.out.println(A[i]);

    }

    for(shape s:A) {
    System.out.println(s.getClass()+","+s.getClass().getSuperclass());

    }


    }

    public double sumAllArea(shape B[])
    {
    double sum=0;
    for(int i=0;i<B.length;i++)
    sum+= B[i].getArea();
    return sum;
    }
    public double sumAllPerimeter(shape B[])
    {
    double sum=0;
    for(int i=0;i<B.length;i++)
    sum+= B[i].getPerimeter();
    return sum;
    }
    }

     

    public class Rectangle extends shape{
    private int length;
    private int width;
    public Rectangle(int length, int width) {//这地方的参数只是形参可以不和父类的实参相同
    this.length = length;
    this.width = width;
    }
    //继承父类
    public double getPerimeter() {//此时不能用abstract
    return 2*(length+width);
    }
    double getArea(){
    return length*width; //调用父类求面积的方法
    }
    public String toString()
    {
    return getClass().getName() + "[ width=" + width + "]"+ "[length=" + length + "]";
    }
    }

    public class Circle extends shape{
    private int radius;

    public Circle(int r) {
    this.radius= r;
    }
    //继承父类
    double getPerimeter(){ //调用父类求周长的方法
    return 2*PI*radius;
    }
    double getArea(){
    return PI*radius*radius; //调用父类求面积的方法
    }
    public String toString()
    {
    return getClass().getName() + "[radius=" + radius + "]";
    }
    }

    程序运行结果:

     

     

    实验3:编程练习2

    编制一个程序,将身份证号.txt中的信息读入到内存中,输入一个身份证号或姓名,询显示对象的姓名、身份证号、年龄、性别和出生地。

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

    public class Demo {
    private static ArrayList<Student>studentlist = null;
    public static void main(String args[]) {

    studentlist = new ArrayList<>();
    Scanner scanner = new Scanner(System.in);
    File file = new File("D:\sfz/身份证号.txt" );
    BufferedReader reader = null;
    try {
    reader = new BufferedReader(new FileReader(file));

    String temp = null;
    while ((temp = reader.readLine()) != null) {
    Scanner linescanner = new Scanner(temp);
    linescanner.useDelimiter(" ");
    String name = linescanner.next();
    String number = linescanner.next();
    String sex = linescanner.next();
    String age = linescanner.next();
    String province =linescanner.nextLine();

    Student student = new Student();
    student.setName(name);
    student.setnumber(number);
    student.setsex(sex);
    student.setage(age);
    student.setprovince(province);
    studentlist.add(student);

    }

    reader.close();
    } catch (IOException e) { //读错
    e.printStackTrace();
    }


    int status=1;
    while (status!=0)
    {

    System.out.println("1:通过姓名查询");
    System.out.println("2:通过身份证号查询");
    System.out.println("0:退出");

    status = scanner.nextInt();
    switch (status) {

    case 1:
    System.out.println("请输入姓名:");
    String scanner1 = scanner.next();

    int nameint = findStudentByName(scanner1);
    if(nameint != -1) {
    System.out.println("查找信息为:身份证号:"
    + studentlist.get(nameint).getnumber() + " 姓名:"
    + studentlist.get(nameint).getName() +" 性别:"
    +studentlist.get(nameint).getsex() +" 年龄:"
    +studentlist.get(nameint).getage()+" 地址:"
    +studentlist.get(nameint).getprovince()
    );


    } break;
    case 2:
    System.out.println("请输入身份证号:");

    String studentid = scanner.next();
    int id = findStudentById(studentid);
    if (id != -1) {
    System.out.println("查找信息为:身份证号:"
    + studentlist.get(id ).getnumber() + " 姓名:"
    + studentlist.get(id ).getName() +" 性别:"
    +studentlist.get(id ).getsex() +" 年龄:"
    +studentlist.get(id ).getage()+" 地址:"
    +studentlist.get(id ).getprovince()
    );


    }break;

    case 0:
    status = 0;
    System.out.println("程序已退出!");
    break;
    default:
    System.out.println("输入错误");
    }
    }
    }

    public static int findStudentByName(String name) {
    int flag = -1;
    int a[];
    for (int i = 0; i < studentlist.size(); i++) {
    if (studentlist.get(i).getName().equals(name)) {
    flag= i;
    }
    }
    return flag;
    }


    public static int findStudentById(String id) {
    int flag = -1;

    for (int i = 0; i < studentlist.size(); i++) {
    if (studentlist.get(i).getnumber().equals(id)) {
    flag = i;
    }
    }
    return flag;

    }
    }

    public class Student {
    private String name;
    private String number ;
    private String sex ;
    private String age;
    private String province;


    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getnumber() {
    return number;
    }
    public void setnumber(String number) {
    this.number = number;
    }
    public String getsex() {
    return sex ;
    }
    public void setsex(String sex ) {
    this.sex =sex ;
    }
    public String getage() {
    return age;
    }
    public void setage(String age ) {
    this.age=age ;
    }
    public String getprovince() {
    return province;
    }
    public void setprovince(String province) {
    this.province=province ;
    }
    }
    /*public void setStudentId(String string) {
    // TODO Auto-generated method stub

    }
    public int getStudentId() {
    // TODO Auto-generated method stub
    return 0;
    }


    }*/

    运行结果:

    实验总结:

          这一周学习第五章知识,学习了继承的相关概念和基本知识,用父类对象可引用子类对象,继承是Java程序设计中的一项核心技术,也是面向对象特征之一,具有层次结构,子类继承父类的域和方法;此外还了解了超类super,知道子类的构造器不能直接访问超类的私有域,必须调用超类构造器的用法,在Java中对象变量是多态的以及抽象类的使用。此次实验由于时间原因,基本都是自主学习,通过课件和课本相结合的方法,在没有老师的帮助指导下,遇到问题都是首先考虑,即便很抽象,比如Equals方法里的知识特别模糊,在完成了所有的测试实验后,下面的两个编程程序,不由自主的停了下来,很愧疚不能完整写下代码,不能达到老师的要求,遇到了好多问题。在接下,我要好好把握时间了,不能抱有抱怨,脚踏实地,更重要的是信息,因为不会才要学

  • 相关阅读:
    hdu 3652 【数位dp】
    02 -body标签中相关标签
    01-html介绍和head标签
    python 核心编程第九章文件
    python核心编程 第七章 字典,集合 练习
    常用链接
    python核心编程 第七章 字典
    python核心编程 第六章 字符串,元组,列表 字符串元组只读不可变。列表可变。
    python核心编程 第五章 数字
    python读取文件中的路径内容,保存到另外的路径中
  • 原文地址:https://www.cnblogs.com/wang963/p/9750084.html
Copyright © 2020-2023  润新知