Java第三次作业 李新磊
Java第三次作业——面向对象基础(封装)
(一)学习总结
1.什么是面向对象的封装性,Java中是如何实现封装性的?试举例说明。
运用private,把类与外界隔离,从而实现属性和方法的隐藏,只能通过类的get、set方法,才能访问这些属性和方法。
例:
无封装性的类,在主函数中可以随意修改值
class Person {
String name;
int age;
person(){
}
}
public class Test{
public static void main(String args[]){
Person p = new Person();
p.name="Absalom";
p.age=20;
System.out.println("姓名: "+p.name+" 年龄: "+p.age);
}
}
属性封装后,不可随意更改,可以用set方法赋值,get方法调用
class Person {
private String name;
private int age;
Person(){
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
public class Test{
public static void main(String args[]){
Person p = new Person();
p.setName("Absalom");
p.setAge(20);
System.out.println("姓名: "+p.getName()+" 年龄: "+p.getAge());
}
}
2.阅读下面程序,分析是否能编译通过?如果不能,说明原因。
(1)
class A{
private int secret = 5;
}
public class Test{
public static void main(String args[]){
A a = new A();
System.out.println(a.secret++);
}
}
用private将属性封装为私有类型时,需要使用setter,getter方法进行调用。
修改为
class test {
public int secret = 5;
}
public class Test {
public static void main(String args[]) {
test a = new test();
System.out.println(a.secret++);
}
}
或
class A{
private int secret = 5;
int getSecret(){
return secret;
}
}
public class Test{
public static void main(String args[]){
A a = new A();
int b=a.getSecret()+1;
System.out.println(b);
}
}
(2)
public class Test{
int x = 50;
static int y = 200;
public static void method(){
System.out.println(x+y);
}
public static void main(String args[]){
Test.method();
}
}
static变量实质上是全局变量,static变量不是所在类的某个具体对象所有,而是该类的所有对象所共有的,静态变量既能被对象调用,也能直接拿类来调用。
非静态方法或类能引用静态变量或方法,但静态变量不能引用非静态方法。
修改为
public class Test{
static int x = 50;
static int y = 200;
public static void method(){
System.out.println(x+y);
}
public static void main(String args[]){
Test.method();
}
}
3.使用类的静态变量和构造方法,可以跟踪某个类创建的对象个数。声明一个图书类,数据成员为编号,书名,书价,并拥有静态数据成员册数记录图书的总数。图书编号从1000开始,每产生一个对象,则编号自动递增(利用静态变量和构造方法实现)。
完整代码
class Book {
//属性封装
private int bookId;
private String bookName;
private double price;
// 声明静态变量
private static int booknumber;
//定义静态代码块对静态变量初始化
static {
booknumber = 1000;
}
//构造方法
public Book(String bookName, double price) {
this.bookName = bookName;
this.price = price;
bookId = booknumber;
booknumber++;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
// 定义方法求图书总册数
public static int totalBook() {
return booknumber - 1000;
}
// 重写toString方法
public String toString() {
return "编号:" + bookId + " 书名:" + this.bookName + " 价格:" + this.price;
}
}
public class Test {
public static void main(String args[]) {
Book[] books = { new Book("c语言程序设计", 29.3),
new Book("数据库原理", 30),
new Book("Java学习笔记", 68) };
System.out.println("图书总数为:" + Book.totalBook());
for (Book book : books) {
System.out.println(book.toString());
}
}
}
4.什么是单例设计模式?它具有什么特点?用单例设计模式设计一个太阳类Sun
单例模式只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例,并且给所有其他对象提供这一实例.
1. 饿汉式:一开始就建立这个单例对象
public class Sun{
private static final Sun instance = new Sun();
private Sun(){
}
public static Sun getInstance(){
return instance;
}
}
2. 懒汉式:在真正用到的时候才去建这个单例对象
public class Sun{
private static Sun instance=null;
public static Sun getInstance()
{
if(instance==null)
{
synchronized(Sun.class)
{
if(instance==null)
instance=new Sun();
}
}
return instance;
}
private Sun(){
}
}
5.理解Java参数传递机制,阅读下面的程序,运行结果是什么?说明理由。
public class Test {
String str = new String("你好 ");
char[] ch = { 'w','o','l','l','d' };
public static void main(String args[]) {
Test test = new Test();
test.change(test.str, test.ch);
System.out.print(test.str);
System.out.print(test.ch);
}
public void change(String str, char ch[]) {
str = "hello";
ch[0] = 'W';
}
}
运行结果: 你好 Wolld
ch[]储存到栈内存内,其地址被change引用,首元素ch[0]被改变为‘W’;str存储到堆内存内,change调用的是str的副本,不能改变str的内容
6.其他总结
评分系统程序中,对5名选手对象进行排序,用到了Comparable接口
此接口强行对实现它的每个类的对象进行整体排序。实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。
自然比较方法 int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
public int compareTo(Mark o) {
if (this.finalscore < o.finalscore) {
return 1;
}
else if (this.finalscore > o.finalscore) { //比较最终得分,sort方法实现按照最终得分从大到小排列
return -1;
}
else {
return 0;
}
}
......
Arrays.sort(player);//sort方法,将5位player对象按照最终得分排序
(二)实验总结
1.职工部门
程序设计思路
- 设计日期类、职工类、部门类、测试类。
- 定义setter、gstter方法,用于属性的赋值与调用。
- 定义toString()方法,用于输出属性值。
- 在类之间进行关联操作。
- 在测试类中进行构造对象数组,将各个对象实例化。
- 编写查找方法,查找员工或部门信息。
问题1.如何实现部门与员工关联
在部门类中定义一个对象数组emps[],存储5名职工对象
employee emps[];
public employee[] getEmployee() {
return emps;
}
public void setEmployee(employee[] emps) {
this.emps = emps;
}
......
员工生日为日期类的对象
worker[i].birthday=time[i];
将5名职工存储到一个部门中
parts[0].setEmployee(new employee[]{worker[0],worker[1],worker[2],worker[3],worker[4]});
设置部门经理
parts[0].setBoss(worker[0]);
2.计算工具
程序设计思路
- 设计一个计算工具类,分别编写球、圆柱、圆锥的体积表面积计算方法,根据产生的几何体类型分别调用。
//运用构造方法的重载,根据产生的几何体的类型,调用不同的构造方法
public tool(int r){//球体
this.r=r;
}
public tool(int r,int h){//圆柱体
this.r=r;
this.h=h;
}
public tool(int r,int l,int h){//圆锥体
this.r=r;
this.l=l;
this.h=h;
}
-
设计一个测试类,随机产生2个不同的圆柱体,圆锥体,球体的尺寸,调用计算工具类分别求它们体积与表面积,再求体积与表面积的累加和。
-
设计一个测试类,随机产生球,圆柱、圆锥体的尺寸,模拟考试,要求用户回答它们的体积和面积,并判断用户的回答是否正确
问题1.如何实现Test类、Exam类的功能(随机产生一组数,最为几何体的数据,并进行计算输出)
Random random=new Random();
r1=random.nextInt(20);
while(r==0){
r=random.nextInt(20);//随机产生1-20之间的整数r1,作为球体的半径
}
tool sphere1=new tool(r1);//声明一个球体对象,半径为r1
System.out.printf(半径为%d的球的表面积 "+sphere1.sphereArea(r1) ,r1);//调用sphereArea(r1)方法,计算球体的表面积
问题2.体积、表面积为double型,在判断用户输入是否正确时出现精度丢失,不能正确判断
运用BigDecimal()类型,将运算结果四舍五入
public double cylinderArea(int r,int h){
double s=2.0*pi*r*r+pi*r*2.0*h;
BigDecimal bg = new BigDecimal(s);
s=bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();//四舍五入,保留两位小数
return s;
}
3.用面向对象编程思想完成评分系统
程序设计思路
- 编写一个选手类,存储序号、姓名、得分、最终得分,编写计算最大值、最小值方法,计算最终得分方法,排序方法
- 编写一个系统类,实现分数的输入与最终得分的有序输出
问题1.不能直接对对象数组排序
错误原因:直接对对象数组进行冒泡排序
//错误代码
public int toSort(player) {
for (int i = 0; i < player.length; i++)
{
for (int j = i + 1; j < player.length; j++)
{
if (player[i].finalscore < player[j].finalscore)
{
Mark.temp=new Mark();
temp=player[j];
player[j]=player[i];
player[i]=temp;
}
}
}
}
解决方法:运用Comparable接口 自然比较方法 int compareTo(T o) 强行对实现它的每个类的对象进行整体排序
public int compareTo(Mark o) {
if (this.finalscore < o.finalscore) {
return 1;
}
else if (this.finalscore > o.finalscore) { //比较最终得分,sort方法实现按照最终得分从大到小排列
return -1;
}
else {
return 0;
}
}
......
Arrays.sort(player);//sort方法,将5位player对象按照最终得分排序
4.用面向对象编程思想编写猜拳游戏
程序设计思路
-
编写ComputerPlayer类,实现电脑功能
-
属性:名称、得分
-
addScore()方法:实现分数加一 show方法:显示电脑的操作
-
public int getNum(){//获取电脑产生的随机数,用于比较输赢
Random random=new Random();
int num = random.nextInt(4);
if(num==0){
num=random.nextInt(4);
}
return num;
}
public void show(){
switch(this.getNum()){
case 1 :
System.out.println("电脑出拳:剪刀");
break;
case 2 :
System.out.println("电脑出拳:石头");
break;
case 3 :
System.out.println("电脑出拳:布");
break;
}
}
-
PersonPlayer类,实现玩家功能
- 属性:名称、得分 show()方法:显示玩家的操作
public void show(int num){
if(num==1){
System.out.println("你出拳: 剪刀");
}
else if(num==2){
System.out.println("你出拳: 石头");
}
else{
System.out.println("你出拳: 布");
}
}
- Game类,实现游戏控制功能
- 属性:总局数、平局数 init():初始化方法 finale():显示对局结果方法
//将电脑、玩家的分数与总局数、平局数初始化
public void init(ComputerPlayer computer,PersonPlayer person){
computer.setScore(0);
person.setScore(0);
this.count=0;
this.counttied=0;
}
//判断对决结果
public void finale(ComputerPayer computer,int num){
if((computer.numrandom+1)==num){
System.out.println("平局");
addCounttied();//如果平局,平局数加一
}
else if((computer.numrandom-num==0)||(num==3&&computer.numrandom==0)){
System.out.println("computer win");//如果电脑赢,电脑分数加一
computer.addScore();
}
else
{
System.out.println("you win");//如果玩家赢,玩家分数加一
person.addScore();
}
}
-
Test类,运行程序
- 编写method()方法,运行游戏过程,最后选择是否进行下一轮时y/n,如果选择继续,则递归调用自身,进行下一次,直到选择结束为止。
public static int method(Game beginstart,ComputerPlayer computer,PersonPlayer person){
Scanner in=new Scanner(System.in);
beginstart.finale(computer,person);//显示对决结果
beginstart.addCount(); //每运行一次,总局数加一
System.out.println("是否进行下一轮 y/n");
String choice;
choice=in.next();
if(choice.equals("y")){
return method(beginstart,computer,person);
}
else{
return 0;
}
}
问题1.统计游戏总次数与平局次数
在运行方法method()中执行beginstart.addCount()方法,每运行一次,总局数加一
在判断对决结果finale(ComputerPayer computer,int num)方法中执行,当对决结果为平局时,执行一次,平局数加一
public void addCount(){
this.count++;
}
public void addCounttied(){
this.counttied++;
}
问题2.如何显示对决结果
获取电脑产生的随机数与玩家输入的数,进行比较
Scanner in=new Scanner(System.in);
System.out.println("请出拳:1.剪刀 2.石头 3.布(请输入相应数字:)");
int num = in.nextInt();
......
public int getNum(){
Random random=new Random();
int num = random.nextInt(3);
return num;
}
......
public void finale(ComputerPayer computer,int num){
if((computer.getNum()+1)==num){//如果两数相等,则平局
System.out.println("平局");
addCounttied();
}
else if((computer.getNum()-num==0)||(num==3&&computer.getNum()==0)){//如果电脑随机数比玩家输入数大1,或者电脑出剪刀(1),玩家出布(3)则电脑胜
System.out.println("computer win");
computer.addScore();
}
else
{
System.out.println("you win");
person.addScore();
}
}
(三)代码托管
http://git.oschina.net/hebau_cs15/Java-CS02lxl

浙公网安备 33010602011771号