• 201871010133 赵永军《面向对象程序设计(java)》第六、七周学习总结


    201871010133 赵永军《面向对象程序设计(java)》第六、七周学习总结

    项目 内容
    这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/
    这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/11605051.html
    作业学习目标

    1、学习第5章内容;

    2、完成实验五;

    3、修改置顶博文《面向对象程序设计课程学习进度条》,记录第五周、第六周、第七周个人编程水平提升参数。

     

     

     

     

     

     

     

     

     

     

     

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

    1.继承:已有类来构建新类的一种机制。档定义了一个新类继承另一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的方法和域以适应新的情况。

      继承的特点:具有层次结构;子类继承了超类的方法和域。

    2.类继承的格式:class 新类名 extends 已有类名

      已有类称为:超类(superclass)、基类(base class) 或父类(parent  class)

      新类称作:子类(subclass)、派生类(derived  class)或孩子类(child class)

        1)继承类中,子类的构造器不能直接访问超类的私有域,必须调用超类构造器,且必须是第一条语句。

        2)子类不能直接访问超类的私有域,必须和其他方法一样使用公有接口。

        3)子类中可以增加域、增加方法或覆盖(override)超类的方法,但是绝不能删除超类的任何域和方法。

        注:java不支持多继承。

    3.多态性:泛指在程序中同一个符号在不同情况下具有不同解释。

      超类方法在子类中可以重写。

      java中,对象变量是多态的。

      继承层次结构中,每个子类对象也可视作超类对象,因此,也可以将子类对象赋给超类变量。如:boss.setBouns(5000);

    4:final类:不允许继承的类,在类的定义中用final修饰符加以说明。

    5:强制转换类型:如果要把一个超类对象赋给一个子类对象变量,就必须进行强制类型转换,格式如下:Manager boss=(Manager)staff【0】;

    6.抽象类:abstract class Person

      1)abstract方法不能被实例化,即只能声明,不能实现!

      2)包含一个或多个抽象方法的类本身必须被声明为抽象类。

    7:Object类:所有类的超类。

      1)Java中的每个类都源于java.lang.Object类。熟悉Object类提供的方法很重要。这样就可以在自己的类中使用它们。

      2)toString()方法:返回所属类名@该对象十六进制形式的内存地址

      3)equals()方法:使用==检测两个引用变量是否指向同一个对象。覆盖equals方法的格式固定为equals(Object obj)

    8:equals方法:用于测试某个对象是否和另一个对象相等。如果两个对象有相同的引用,则他们一定相等。

    9:hasCode方法:导出某个对象的散列码(任意整数)。

      两个相等对象的散列码相等。

    10:toString方法:返回一个代表该对象域值的字符串。

      格式:类名【域值】

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

      1)枚举类是一个类,它的隐含超类是java.lang.Enum。

      2)枚举值并不是整数或其它类型,是被声明的枚举类的自身实例

    12、继承设计的技巧

      1) 将公共操作和域放在超类。

      2)不要使用受保护的域。

      3)使用继承实现“is-a”关系。

      4)除非所有继承的方法都有意义,否则就不要使用继承。

      5)在覆盖方法时,不要改变预期的行为。

      6)使用多态,而非类型信息。

    第二部分:实验部分

    1、实验目的与要求

    (1) 理解继承的定义;

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

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

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

    2、实验内容和步骤

    实验1:测试程序1

    1)在elipse IDE中编辑、调试、运行程序5-1——5-3(教材152页——153页);

    2)掌握子类的定义与用法;

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

    4)删除程序中Manager类、ManagerTest类,背录删除类的程序代码,在代码录入中理解父类与子类的关系和使用特点。

     程序如下:

     1 /**
     2  * This program demonstrates inheritance.
     3  * @version 1.21 2004-02-21
     4  * @author Cay Horstmann
     5  */
     6 public class ManagerTest//主类:创建一个Manager类
     7 {
     8    public static void main(String[] args)
     9    {
    10     
    11       Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    12       boss.setBonus(5000);//bouns在Manager类中赋初值为空,此处用更改器更改为5000
    13 
    14       Employee[] staff = new Employee[3];//用三个Employee类填充Staff数组
    15 
    16       staff[0] = boss;//已定义boss的属性,此处直接调用
    17       staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
    18       staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);
    19       
    20       for (Employee e : staff)
    21          System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
    22    }
    23 }

    因为主类中有Employee类,所以需新建Employee类,程序如下:

     1 import java.time.*;
     2 
     3 public class Employee//用户自定义类
     4 {
     5    private String name;
     6    private double salary;
     7    private LocalDate hireDay;
     8    //创建三个私有属性
     9 
    10    public Employee(String name, double salary, int year, int month, int day)//构造器
    11    {
    12       this.name = name;//name调用构造器的name
    13       this.salary = salary;
    14       hireDay = LocalDate.of(year, month, day);
    15    }
    16 
    17    public String getName()
    18    {
    19       return name;
    20    }
    21 
    22    public double getSalary()
    23    {
    24       return salary;
    25    }
    26 
    27    public LocalDate getHireDay()
    28    {
    29       return hireDay;
    30    }
    31 //访问器
    32    public void raiseSalary(double byPercent)
    33    {
    34       double raise = salary * byPercent / 100;
    35       salary += raise;
    36    }//定义两个局部变量
    37 }

    在Employee类中,有Manager类,而Manager类中部分属性在Employee中已定义,故使用继承来新建Manager类,程序如下:

     1 public class Manager extends Employee//子类:Manager类继承Employee类
     2 {
     3    private double bonus;//创建一个私有属性bouns
     4 
     5    /**
     6     * @param name the employee's name
     7     * @param salary the salary
     8     * @param year the hire year
     9     * @param month the hire month
    10     * @param day the hire day
    11     */
    12    public Manager(String name, double salary, int year, int month, int day)//构造器
    13    {
    14       super(name, salary, year, month, day);//子类不用再重新定义,直接调用超类中已定义的属性
    15       bonus = 0;//bouns的初值赋为空
    16    }
    17 
    18    public double getSalary()//访问器
    19    {
    20       double baseSalary = super.getSalary();
    21       return baseSalary + bonus;
    22    }//定义两个局部变量
    23 
    24    public void setBonus(double b)//更改器
    25    {
    26       bonus = b;
    27    }
    28 }

    程序运行结果如图所示:

     oo方法即面向对象方法,而oo风格的特点是封装、继承、多态。

    测试程序2:

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

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

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

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

    5)删除程序中Person类、PersonTest类,背录删除类的程序代码,在代码录入中理解抽象类与子类的关系和使用特点。

    程序如下:

     1 /**
     2  * This program demonstrates abstract classes.
     3  * @version 1.01 2004-02-21
     4  * @author Cay Horstmann
     5  */
     6 public class PersonTest//主类
     7 {
     8    public static void main(String[] args)
     9    {
    10       Person[] people = new Person[2];
    11 
    12       //用Employee类和Student类填充people数组
    13       people[0] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
    14       people[1] = new Student("Maria Morris", "computer science");
    15 
    16       //打印出所有person类的名字和其他描述
    17       for (Person p : people)
    18          System.out.println(p.getName() + ", " + p.getDescription());
    19    }
    20 }

    因主类中有Person类,而Person类是一个抽象类,故需新建一个抽象类Person类,程序如下:

     1 public abstract class Person//抽象类:Person
     2 {
     3    public abstract String getDescription();
     4    private String name;//传建一个私有属性
     5 
     6    public Person(String name)//构造器
     7    {
     8       this.name = name;
     9    }
    10 
    11    public String getName()//访问器
    12    {
    13       return name;
    14    }
    15 }

    在主类中,Employee类和student类都是person类的子类,所以新建两个子类,程序如下:

    Student类:

     1 public class Student extends Person//子类:Student类继承Person类
     2 {
     3    private String major;//创建一个私有属性major
     4 
     5    /**
     6     * @param nama the student's name
     7     * @param major the student's major
     8     */
     9    public Student(String name, String major)//构造器
    10    {
    11     //将n传递给超类构造函数
    12       super(name);//子类直接调用超类中的name属性
    13       this.major = major;
    14    }
    15 
    16    public String getDescription()//访问器
    17    {
    18       return "a student majoring in " + major;
    19    }
    20 }

    Employee类:

     1 import java.time.*;
     2 
     3 public class Employee extends Person//子类:Employee类继承Person类
     4 {
     5    private double salary;
     6    private LocalDate hireDay;
     7 //构建两个私有属性
     8    public Employee(String name, double salary, int year, int month, int day)//构造器
     9    {
    10       super(name);//子类中不再重新定义,直接调用超类中的name
    11       this.salary = salary;
    12       hireDay = LocalDate.of(year, month, day);
    13    }
    14 
    15    public double getSalary()
    16    {
    17       return salary;
    18    }
    19 
    20    public LocalDate getHireDay()
    21    {
    22       return hireDay;
    23    }
    24 
    25    public String getDescription()
    26    {
    27       return String.format("an employee with a salary of $%.2f", salary);
    28    }
    29 //访问器
    30    public void raiseSalary(double byPercent)
    31    {
    32       double raise = salary * byPercent / 100;
    33       salary += raise;
    34    }//定义两个局部变量
    35 }

    程序运行结果如图所示:

    测试程序3:

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

    2)掌握Object类的定义及用法;

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

    程序如下:

     1 /**
     2  * This program demonstrates the equals method.
     3  * @version 1.12 2012-01-26
     4  * @author Cay Horstmann
     5  */
     6 public class EqualsTest//主类
     7 {
     8    public static void main(String[] args)
     9    {
    10       Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
    11       Employee alice2 = alice1;
    12       Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
    13       Employee bob = new Employee("Bob Brandson", 50000, 1989, 10, 1);
    14 
    15       System.out.println("alice1 == alice2: " + (alice1 == alice2));
    16 
    17       System.out.println("alice1 == alice3: " + (alice1 == alice3));
    18 
    19       System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));
    20 
    21       System.out.println("alice1.equals(bob): " + alice1.equals(bob));
    22 
    23       System.out.println("bob.toString(): " + bob);
    24 
    25       Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    26       Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    27       boss.setBonus(5000);//在子类中赋初值为空,主类中用更改器更改为5000
    28       System.out.println("boss.toString(): " + boss);
    29       System.out.println("carl.equals(boss): " + carl.equals(boss));
    30       System.out.println("alice1.hashCode(): " + alice1.hashCode());
    31       System.out.println("alice3.hashCode(): " + alice3.hashCode());
    32       System.out.println("bob.hashCode(): " + bob.hashCode());
    33       System.out.println("carl.hashCode(): " + carl.hashCode());
    34    }
    35 }

    用户自定义类Employee:

     1 import java.time.*;
     2 import java.util.Objects;
     3 
     4 public class Employee//用户自定义类
     5 {
     6    private String name;
     7    private double salary;
     8    private LocalDate hireDay;
     9    //创建三个私有属性
    10    public Employee(String name, double salary, int year, int month, int day)
    11    {
    12       this.name = name;
    13       this.salary = salary;
    14       hireDay = LocalDate.of(year, month, day);
    15    }
    16 
    17    public String getName()
    18    {
    19       return name;
    20    }
    21 
    22    public double getSalary()
    23    {
    24       return salary;
    25    }
    26 
    27    public LocalDate getHireDay()
    28    {
    29       return hireDay;
    30    }
    31    //访问器
    32    public void raiseSalary(double byPercent)
    33    {
    34       double raise = salary * byPercent / 100;
    35       salary += raise;
    36    }//定义两个局部变量
    37 
    38    public boolean equals(Object otherObject)
    39    {
    40       //快速测试几个类的根是否相同,即是否是同一个超类
    41       if (this == otherObject) return true;
    42 
    43       //如果显式参数为空必须返回false
    44       if (otherObject == null) return false;
    45 
    46       //如果几个类不匹配,则它们不相等
    47       if (getClass() != otherObject.getClass()) return false;
    48 
    49       //其他对象是非空Employee类
    50       Employee other = (Employee) otherObject;
    51 
    52       //测试是否具有相同的值
    53       return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    54    }
    55 
    56    public int hashCode()//重写hashcode方法,使相等的两个对象获取的HashCode也相等
    57    {
    58       return Objects.hash(name, salary, hireDay); 
    59    }
    60 
    61    public String toString()//把其他类型的数据转为字符串类型的数据
    62    {
    63       return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay
    64             + "]";
    65    }
    66 }

    子类Manager:

     1 public class Manager extends Employee//子类:Manager类继承Employee类
     2 {
     3    private double bonus;//创建私有属性bouns
     4 
     5    public Manager(String name, double salary, int year, int month, int day)
     6    {
     7       super(name, salary, year, month, day);//子类直接调用超类中已创建的属性
     8       bonus = 0;//给bouns赋初值为空
     9    }
    10 
    11    public double getSalary()//访问器
    12    {
    13       double baseSalary = super.getSalary();
    14       return baseSalary + bonus;
    15    }
    16 
    17    public void setBonus(double bonus)//更改器
    18    {
    19       this.bonus = bonus;
    20    }
    21 
    22    public boolean equals(Object otherObject)////快速测试几个类的根是否相同,即是否是同一个超类
    23    {
    24       if (!super.equals(otherObject)) return false;
    25       Manager other = (Manager) otherObject;
    26       //  //使用super.equals检查这个类和其他是否属于同一个类
    27       return bonus == other.bonus;
    28    }
    29 
    30    public int hashCode()//重写hashcode方法,使相等的两个对象获取的HashCode也相等
    31    {
    32       return java.util.Objects.hash(super.hashCode(), bonus);
    33    }
    34 
    35    public String toString()//把其他类型的数据转为字符串类型的数据
    36    {
    37       return super.toString() + "[bonus=" + bonus + "]";
    38    }
    39 }

    运行结果如图所示:

    实验2编程练习

    Ÿ 定义抽象类Shape:

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

     方法:public double getPerimeter();public double getArea())。

    Ÿ RectangleCircle继承自Shape类。

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

    Ÿ main方法中

      1输入整型值n,然后建立n个不同的形状。如果输入rect,则再输入长和宽。如果输入cir,则再输入半径。
      2) 然后输出所有的形状的周长之和,面积之和。并将所有的形状信息以样例的格式输出。
      3) 最后输出每个形状的类型与父类型使用类似shape.getClass()(获得类型),shape.getClass().getSuperclass()(获得父类型);

    思考sumAllAreasumAllPerimeter方法放在哪个类中更合适?

    输入样例:

    3

    rect

    1 1

    rect

    2 2

    cir

    1

    输出样例:

    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

    主类Work:

     1 import java.util.Scanner;
     2 
     3 public class Work
     4 {
     5 
     6     public static void main(String[] args) 
     7     {
     8         Scanner in = new Scanner(System.in);
     9         String rect = "rect";
    10         String cir = "cir";
    11         System.out.print("请输入所需图形的形状个数:");
    12         int n = in.nextInt();
    13         shape[] count = new shape[n];
    14         for(int i=0;i<n;i++)
    15         {
    16             System.out.println("请输入图形形状:");
    17             String input = in.next();
    18             if(input.equals(rect))
    19             {
    20                 double length = in.nextDouble();
    21                 double width = in.nextDouble();
    22                 System.out.println("长方形:"+"长:"+length+"  宽:"+width);
    23                 count[i] = new Rect(length,width);
    24             }
    25             if(input.equals(cir)) 
    26             {
    27                 double radius = in.nextDouble();
    28                 System.out.println("圆:"+"半径:"+radius);
    29                 count[i] = new Cir(radius);
    30             }
    31         }
    32         Work c = new Work();
    33         System.out.println(c.sumAllPerimeter(count));
    34         System.out.println(c.sumAllArea(count));
    35         for(shape s:count) 
    36         {
    37 
    38             System.out.println(s.getClass()+",  "+s.getClass().getSuperclass());
    39         }
    40     }
    41 
    42     public double sumAllArea(shape count[])
    43     {
    44          double sum = 0;
    45          for(int i = 0;i<count.length;i++)
    46              sum+= count[i].getArea();
    47          return sum;
    48     }
    49     
    50     public double sumAllPerimeter(shape count[])
    51     {
    52          double sum = 0;
    53          for(int i = 0;i<count.length;i++)
    54              sum+= count[i].getPerimeter();
    55          return sum;
    56     }
    57     
    58 }

    抽象类Shape:

    1 public abstract class shape
    2  {
    3      double PI = 3.14;
    4      public abstract double  getPerimeter();
    5      public abstract double  getArea();
    6  }

    子类Rect:

     1 public class Rect extends shape
     2 {
     3     private double width;
     4     private double length;
     5     public Rect(double w,double l)
     6     {
     7         this.width = w;
     8         this.length = l;
     9     }
    10     public double getPerimeter()
    11     {
    12         double Perimeter = 2*(length+width);
    13         return Perimeter;
    14     }
    15     public double getArea()
    16     {
    17         double Area = length*width;
    18         return Area;
    19     }
    20 }

    子类Cir:

     1 public class Cir extends shape
     2 {
     3     private double radius;
     4  
     5     public Cir(double radius2) {
     6         // TODO Auto-generated constructor stub
     7     }
     8     public double getPerimeter()
     9     {
    10         double Perimeter=2*PI*radius;
    11         return Perimeter;
    12     }
    13     public double getArea()
    14     {
    15         double Area=PI*radius*radius;
    16         return Area;
    17     }
    18 }

    程序运行结果如图所示:

     3. 实验总结

            通过前一周的学习,我初步掌握了有关继承类的知识。在编写程序时,使用继承类更能简化程序。通过课堂学习和课后运行程序,了解了子类和父类的关系。另外,学习了抽象类的用法,在运行程序的过程中,加深了对它的理解。在完成编程练习时,自己通过查书查资料,并仿照书上给的源程序,写出了大概的程序。但在细节上,程序总是会有错误,最后通过查找资料和不断的修改完成了本次实验。通过这次实验,我深深认识到,很多知识一定要看书,并在课后多敲代码练习。对于很多自己还不理解的知识,自己定会加强学习,希望之后的实验中,问题能够减少。

  • 相关阅读:
    oracle ORA01001,请求资源正忙或无效
    Flex[Embed(source='assets/error.png')]无法解析用于转换的代码错误
    正在覆盖未标记为 override 的函数
    LINUX umask详解
    C++服务器学习路线
    计算kappa系数
    umask的含义及设置
    Seurat的各种数据成员访问
    GAN训练判别器和生成器时的顺序与detach
    autograd.grad 学习
  • 原文地址:https://www.cnblogs.com/zhaoyongjun0911/p/11606715.html
Copyright © 2020-2023  润新知