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

posted on 2017-04-01 17:33  押沙龙  阅读(439)  评论(2)    收藏  举报