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

项目

内容

这个作业属于哪个课程

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

这个作业的要求在哪里

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

作业学习目标

  1. 掌握四种访问权限修饰符的使用特点;
  2. 掌握Object类的用途及常用API;
  3. 掌握ArrayList类的定义方法及用途;
  4. 掌握枚举类定义方法及用途;
  5. 结合本章实验内容,理解继承与多态性两个面向对象程序设计特征,并体会其优点。

 

实验内容和步骤

实验1:(20分)

“System.out.println(...);”语句处按注释要求设计代码替换...,观察代码录入中IDE提示,以验证四种权限修饰符的用法。

代码如下:

class Parent {
	private String p1 = "这是Parent的私有属性";
	public String p2 = "这是Parent的公有属性";
	protected String p3 = "这是Parent受保护的属性";
	String p4 = "这是Parent的默认属性";
	private void pMethod1() {
		System.out.println("我是Parent用private修饰符修饰的方法");
	}
	public void pMethod2() {
		System.out.println("我是Parent用public修饰符修饰的方法");
	}
	protected void pMethod3() {
		System.out.println("我是Parent用protected修饰符修饰的方法");
	}
	void pMethod4() {
		System.out.println("我是Parent无修饰符修饰的方法");
	}
}
class Son extends Parent{
	private String s1 = "这是Son的私有属性";
	public String s2 = "这是Son的公有属性";
	protected String s3 = "这是Son受保护的属性";
	String s4 = "这是Son的默认属性";
	public void sMethod1() {
		System.out.println( );//分别尝试显示Parent类的p1、p2、p3、p4值
		System.out.println("我是Son用public修饰符修饰的方法");
	}
	private void sMethod2() {
		System.out.println("我是Son用private修饰符修饰的方法");
	}
	protected void sMethod() {
		System.out.println("我是Son用protected修饰符修饰的方法");
	}
	void sMethod4() {
		System.out.println("我是Son无修饰符修饰的方法");
	}	
}
public class Demo {
	public static void main(String[] args) {
		Parent parent=new Parent();
		Son son=new Son();
		System.out.println( );	//分别尝试用parent调用Paren类的方法、用son调用Son类的方法	
	}
}

 1.1分别尝试显示Parent类的p1、p2、p3、p4值

   结果如下:

                       

 

                    

 

由上实验结果可知Parent类的P1方法是不能显示的,因为P1的权限修饰符用的是private,表示parent的私有属性,son在继承后也不能显示;

1.2分别尝试用parent调用Paren类的方法、用son调用Son类的方法

结果如下:

             

 

                   

 

 

 private是Parent的私有属性,public是Parent的公有属性,protected 这是Parent受保护的属性,String 是Parent的默认属性。

                   

 

 

 

 

                         

 

 

 

 同样,private是son的私有属性,public是son的公有属性,protected 这是son受保护的属性,String 是son的默认属性。

1.私有权限 private
private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部 类,不考虑内部类)。被private修饰的成员,只能在定义它们的类中使用,在 其他类中不能调用。
2.默认权限 default
类,数据成员,构造方法,方法成员,都能够使用默认权限,即不写任何关 键字。默认权限即同包权限,同包权限的元素只能在定义它们的类中,以及同包 的类中被调用。
3.受保护权限protected
protected可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外 部类,不考虑内部类)。被protected修饰的成员,能在定义它们的类中,同包 的类中被调用。如果有不同包的类想调用它们,那么这个类必须是定义它们的类 的子类。
4.公共权限 public
public可以修饰类,数据成员,构造方法,方法成员。被public修饰的成员 ,可以在任何一个类中被调用,不管同包或不同包,是权限最大的一个修饰符。

实验2:测试程序1(15分)

5-8代码如下

package equals;
 
/**
 * This program demonstrates the equals method.
 * @version 1.12 2012-01-26
 * @author Cay Horstmann
 */
public class EqualsTest                  // 实现Employee类和Manager类的equals,hashCode方法
{
   public static void main(String[] args)
   {
      var alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15); //初始化alice1
      var alice2 = alice1;                                           //将Alice1的值赋给alice2
      var alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15); //初始化alice3
      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());  //在这里实现Employee类和Manager类的hashCode方法
      System.out.println("carl.hashCode(): " + carl.hashCode());
   }
}

  

5-9代码如下:

package equals;
 
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;    // 返回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实例域设置为新值;
   }
 
   public boolean equals(Object otherObject)
   {
      // a quick test to see if the objects are identical
      if (this == otherObject) return true;  //检测this与otherObject是否引用同一个对象;
 
      // must return false if the explicit parameter is null
      if (otherObject == null) return false;   //检测otherObject是否为null,如果为null返回false;
 
      // if the classes don't match, they can't be equal
      if (getClass() != otherObject.getClass()) return false; //getClass方法将返回一个对象所属的类;
 
      // now we know otherObject is a non-null Employee
      var other = (Employee) otherObject;    //知道otherObject是一个非空的Employee;
 
      // test whether the fields have identical values   测试字段是否具有相同的值;
      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代码如下:

package equals;
 
public class Manager extends Employee   //由继承Employee类来定义Manager类的格式,关键字extend表示继承
{
   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;
      // super.equals checked that this and other belong to the same class
      return bonus == other.bonus; //检查这个和其他是否属于同一个类;
   }
 
   public int hashCode()
   {
      return java.util.Objects.hash(super.hashCode(), bonus);
   }
 
   public String toString()
   {
      return super.toString() + "[bonus=" + bonus + "]";
   }
}

  

5-8,5-9,5-10运行截图:

删除程序中Employee类、Manager类中的equals()hasCode()toString()方法,背录删除方法,在代码录入中理解类中重写Object父类方法的技术要点。

Employee

package equals;

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


@Override
public boolean equals(Object otherObject) {
    // TODO Auto-generated method stub
    if(this==otherObject) return true;
    if(this==null) return false;
    if(getClass() != otherObject.getClass()) return false;
    Employee other=(Employee)otherObject;
    return Objects.equals(name,other.name)&&salary == other.salary&&Objects.equals(hireDay,other.hireDay);
}
@Override
public int hashCode() {
    // TODO Auto-generated method stub
    return Objects.hash(name,salary,hireDay);
}

@Override
public String toString() {
    // TODO Auto-generated method stub
    return getClass().getName()+"[name="+name+",salary="+salary+",hireday="+hireDay+"]";
}
  

}

Manger

package equals;

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);
        // TODO Auto-generated constructor stub
         bonus = 0;
    }
    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    @Override
    public double getSalary() {
        // TODO Auto-generated method stub
        double baseSalary= super.getSalary();
        return baseSalary+bonus;
    }
    @Override
    public boolean equals(Object otherObject) {
        // TODO Auto-generated method stub
        if(!super.equals(otherObject)) return false;
        Manager other=(Manager)otherObject;
        return bonus==other.bonus;
    }
    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return super.hashCode()+17*new Double(bonus).hashCode();
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString()+"[bonus="+bonus+"]";
    }
 
}

 运行结果:

 

 

equals方法:

  Object类中的equals方法用于检测某个对象是否同另一个对象相等。它在Object类中的实现是判断两个对象是否相等的引用。如果两个对象具有相同的引用,它们一定是相等的;

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

  定义子类的equals方法时,可调用超累的equals方法;super. equals (otherObjecct)

hashCode方法:

  Object类中的哈hashCode方法导出某个对象的散列码。散列码时任意整数,表示dui过的存储地址;两个相等对象的散列码相等。

toString方法:

  Object类中的toString方法返回一个代表该类对象域值的字符串;定义子类的toString方法时,可先调用超类的toString方法;

  super.toString()

  toString方法是非常重要的调试工具。标准类库中,多数类定义了toString方法,以便用户获得对象状态的必要信息。

 实验2:测试程序2(15分)

5-11代码:

package arrayList;

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)
   {
	// 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());                 //打印每个雇员的信息;
   }
}

  

package inheritance;

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;       //取得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实例域设置为新值;
   }
}

程序运行结果:

  

 

 

设计适当的代码,测试ArrayList类的set()get()remove()size()等方法的用法。

代码如下:

package arrayList;
 
import java.util.*;
 
/**
 * This program demonstrates the ArrayList class.
 * @version 1.11 2012-01-26
 * @author Cay Horstmann
 */
public class ArrayListTest
{
   private static final Employee element = null;
   private static final int index = 0;
 
   public static void main(String[] args)
   {
      // fill the staff array list with three Employee objects
      ArrayList<Employee> staff = new ArrayList<Employee>();    //构造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));
      ArrayList<Employee> list = new ArrayList<Employee>();
       
      int size=staff.size();
      System.out.println("arrayList中的元素有:"+size);
      for(int i=0;i<staff.size();i++)
      {
          Employee e=staff.get(i);
          System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay="
                    + e.getHireDay());
      }
      staff.set(0, new Employee("llx", 20000, 1999, 11, 06));
      Employee e=staff.get(0);
      System.out.println("修改后为:name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay="
                + e.getHireDay());
       
  
      staff.remove(2);
      System.out.println("删除第一个数据后:");
      int size1=staff.size();
      System.out.println("arrayList中的元素有:"+size1);
      for(int i=0;i<staff.size();i++)
      {
          Employee p=staff.get(i);
          System.out.println("name=" + p.getName() + ",salary=" + p.getSalary() + ",hireDay="
                    + p.getHireDay());
      }
      
      // raise everyone's salary by 5%
      for (Employee e1 : staff)    
         e1.raiseSalary(5);                   //调用raiseSalary的方法提高雇员薪水5%;
 
      // print out information about all Employee objects
      for (Employee e1 : staff)   
         System.out.println("name=" + e1.getName() + ",salary=" + e1.getSalary() + ",hireDay="
            + e1.getHireDay());                 //打印每个雇员的信息;
   }
}

程序运行结果

 

 

ArrayList中的方法:

构造方法:

public ArrayList (int initialCapacity);      //用指定的基本类型(Base_Type)和初始容量(initialCapacity)创建一个空的ArrayList

返回索引处的元素:

public Base_Type get(int index);     //类似于返回数组的a[index],同样的,index不在定义范围之内的话会抛出IndexOutOfBoundException异常

添加元素的方法:

public boolean add(Base_Type newElement);      //将指定位置处的元素添加到主叫ArrayList的末尾,添加成功则返回true;

删除元素的方法:

public Base_Type remove(int index)       //删除并返回指定索引处的元素,同理,index不能越界,否则回抛出异常;

查找方法:

public boolean contain(Object target);       //返回第一个等于target的元素的索引。该方法使用equals方法测试是否相等,如果没有找到target,则返回-1。

内存管理:

public boolean isEmpty();

制作一个副本:

public Object toArray();           //返回一个包含该列表中的所有元素的值。元素顺序保持不变。

 

实验2:测试程序3(15分)

5-12代码如下:

package enums;

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);
      System.out.print("Enter a size: (SMALL, MEDIUM, LARGE, EXTRA_LARGE) ");
      String input = in.next().toUpperCase();
      Size size = Enum.valueOf(Size.class, input); //to string 的逆用方法是静态方法
      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;   //所有枚举类型都是Enum的子类;
}

  程序运行结果:

 

删除程序中Size枚举类,背录删除代码,在代码录入中掌握枚举类的定义要求。

代码如下:

package enums;

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);
      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; }
   @Override
public String toString() {
    // TODO Auto-generated method stub
    return super.toString();
}


   public String getAbbreviation() {
    return abbreviation;
}
public void setAbbreviation(String abbreviation) {
    this.abbreviation = abbreviation;
}


private String abbreviation;
}

  

代码如下:

枚举类:1.枚举类是一个类,它的隐含超类是java.lang.Enum。 2.枚举值并不是整数或其它类型,是被声明的枚举类的自身实例,例如A是Grade的一个实例。

               3.枚举类不能有public修饰的构造函数,构造函数都是隐含private,编译器自动处理。4. 枚举值隐含都是由public、static、final修饰的,无须自己添加这些修饰符。

               5.在比较两个枚举类型的值时,永远不需要调用equals方法,直接使用”==”进行相等比较。

 

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

录入以下代码,结合程序运行结果了解方法的可变参数用法

代码如下:

public class TestVarArgus {  
    public static void dealArray(int... intArray){  
        for (int i : intArray)  
            System.out.print(i +" ");  
          
        System.out.println();  
    }        
    public static void main(String args[]){  
        dealArray();  
        dealArray(1);  
        dealArray(1, 2, 3);  
    }  
}

运行结果:

java方法的可变参数用法:

可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。

注意:可变参数必须位于最后一项。当可变参数个数多于一个时,必将有一个不是最后一项,所以只支持有一个可变参数。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。

在JavaSE5中加入了可变参数功能,用法示例为: public void printArray(Object … args){} 

                                          参数形式变成了:类型+三个黑点+参数名 

作用: 1.可以再不知道参数个数的情况下传入对象进去。 2.可以为应用于单个参数或多个参数。 

 

实验3:编程练习(10分)

编程练习:参照输出样例补全程序,使程序输出结果与输出样例一致。

代码如下:

public class Demo {
	public static void main(String[] args) {
		Son son = new Son();
		son.method();
	}
}
class Parent {
	Parent() {
		System.out.println("Parent's Constructor without parameter");
	}
	Parent(boolean b) {
		System.out.println("Parent's Constructor with a boolean parameter");
	}
	public void method() {
		System.out.println("Parent's method()");
	}
}
class Son extends Parent {
//补全本类定义
	Son(){
	      super(false);
	      System.out.println("Son's Constructor without parameter");
	    }
	    public void method() {
	        System.out.println("Son's method()");
	        super.method();
	    }
}

运行结果:

 

 

3. 实验总结:(15分)

     通过这次实验,掌握四种访问权限修饰符的使用特点,对private和protect的用法需要熟记,以及Object类的用途及常用API;测试程序2中掌握ArrayList类的定义方法及用法,程序3中对枚举类定义方法及用途有了解,结合本章实验内容,理解继承与多态性两个面向对象程序设计特征,并体会其优点。另外,学习了抽象类的用法,在运行程序的过程中,加深了对它的理解。将会程序分装模块化,使得我对问题有了一定的了解并且尝试解决。在对程序进行重写后,代码录入中对Object父类方法和枚举类的技术要有了更深的理解,同时实验了当子类与父类存在于不同的包里的情况。总之,对继承这一章的内容的基础知识和技巧,重要的知识点都有了掌握。

 

posted on 2019-10-14 20:32  201871010110-李华  阅读(81)  评论(0编辑  收藏  举报