- 博文正文开头格式:(2分)
项目 |
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11654436.html |
作业学习目标 |
|
实验内容和步骤
实验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父类方法和枚举类的技术要有了更深的理解,同时实验了当子类与父类存在于不同的包里的情况。总之,对继承这一章的内容的基础知识和技巧,重要的知识点都有了掌握。