Java面向对象:实验二作业剖析

设计一个简单的班级管理系统,满足如下要求:

  • a.) 设计学生类Student,包含学号(String型)、姓名(String型)、性别(‘M’/'F’代表男/女)、年龄(int型)、是否党员(boolean型)、语文(double型)、数学(double型)等信息,要能够方便输出学生信息;
  • b.) 设计班级类BanJi,其中创建班级时可指定班级的最大容量。可向班级中批量增加学生信息,以及打印输出班级中所有学生的信息。
import java.util.Scanner;
class Student{
   String id, name;  char sex; int age; boolean isdy; double yw,sx; //定义属性集
   Student(String i, String n, char s, int a, boolean dy, double yw1, double sx1){
              //构造函数:与类同名、无返回值、不得return 值、通过new调用、
              // 一旦写了构造函数,系统就不再提供默认的(即无参)构造函数
              //构造函数的作用:对象构造时初始化对象中的各属性
              id=i; name=n; sex=s; age=a; isdy=dy; yw=yw1; sx=sx1; //对各属性初始化
   }
   public String toString(){//此函数在用System.out.print(s)打印对象s时(s是Student型对象),会被自动调用
   	   //换言之,此处控制如何输出学生信息(即返回的字符串)
   	   String dy=(isdy==true)?"中共党员": "非党员";
   	   String sex1="未知";
   	   if(sex=='M'||sex=='m') sex1="男";
   	  else if(sex=='F'||sex=='f') sex1="女";
   	   return  id+"   "+name+"   "+sex1+"  "+age+"  " +dy+"  "+sx+"  "+yw;
   }
   void show(){  
       System.out.print(this);
    }
}
class BanJi{//班级类,实际上就是存储学生的顺序表(数组+表长)
    Student [] st; //注:此处并未创建数组对象,仅仅是数组的引用(即指针)
    int  len;
    BanJi(int max){ 
         st=new Student[max]; //注:此处创建的是数组对象,而非Student对象(用的是方括号而非圆括号)
         //len=0;  //注:此句可省略,因为对象中的所有属性变量均会被默认初始化(即均有默认值 0、false、null)
   }
   void append(){//向班级中批量增加学生元素
   	   //需要Scanner:导入、造对象、取数据
   	   Scanner sc=new Scanner(System.in); //创建Scanner对象
   	   System.out.print("请输入一组学生信息,格式如下:\n");
   	   System.out.print("001   张三   M  18  true  78.1  89.2  \n");
   	   System.out.print("请按照上述格式输入:\n");
   	   String id1, name1;  char sex1;  int age1; boolean dy; double yw1; double sx1;
   	   int i=0;
   	   while(!sc.hasNext("0")){//设置一个终止符,调用hasNext()的重载方法hasNext(String patten)!sc.hasNext("0")
   	   	   id1=sc.next(); //注next()可用于读取字符串,默认以空白(包括空格、\t、\n)为间隔
   	   	   name1=sc.next();
   	   	   String s=sc.next(); //先按字符串方式读入性别(如"M");
   	   	   sex1=s.charAt(0); //取字符串s的第一个字符;
   	   	   age1=sc.nextInt();
   	   	   dy=sc.nextBoolean();
   	   	   yw1=sc.nextDouble();
   	   	   sx1=sc.nextDouble();
   	   	   //必须创建一个Student型对象,并将其填入数组st
   	   	   st[i]=new Student(id1,name1,sex1,age1,dy,yw1,sx1); 
   	   	   i++; 
   	   }//end-while
   	   //强调:必须输入结束符才能令hasNext()为假,在windows/dos中,输入的是ctrl+Z
   	   //另外,在诸如eclipse、jcreator等集成环境中,输入的ctrl+z会被平台过滤,因此很难结束
   	   len=i;
   }
   void show(){//显示班级中所有学生信息
   	   for(int i=0; i<len; i++)
   	   	   System.out.println(st[i] ); //直接打印对象
   	 System.out.println("=================");
   	 System.out.println("st[1].show(): ");st[1].show();
   	 //System.out.println("st[10].show(): ");st[10].show();
   }
}
class App{
   public static void main(String[] x){
       //必须先创建班级顺序表 . 类比:顺序表对象就像一个带围墙的大院子,数组就是院子中的一排房子
       BanJi bj=new BanJi(80);
       bj.append();
       bj.show();
       
   }
}

总结:

  • 1、系统性地学习了Scanner读取不同类型数据、读取未知数量的数据(haxNext()–面向String型、hasNextInt()、hasNextDouble())、如何结束输入(ctrl+Z);
  • 2、回顾了构造函数的使用
  • 3、重点:明晰: Student[] s=new Student[100]; 创建的是【一个】数组对象,而非Student对象
    注:s是【一个Student[]型】数组对象,内有100个空指针(即null),
    如果希望使用st[i].show(); ,st[i]必须先创建对象,然后才能使用。
    即:st[i]=new Student(…); //注此处使用圆括号,即调用了Student的构造函数
    否则,将会产生空指针引用异常。如BanJi类中show()的最后一行,若未输入11个元素,就会产生空指针引用异常

完成两个复数的运算:

 
public class Complex
{
    private double real,im;                //实部,虚部

    public Complex(double real, double im) //构造方法
    {
        this.real = real;
        this.im = im;
    }
    
    public Complex(double real)            //构造方法重载
    {
        this(real,0);
    }
    
    public Complex()
    {
        this(0,0);
    }
    
    public Complex(Complex c)              //拷贝构造方法
    {
        this(c.real,c.im);
    }
    
    public boolean equals(Complex c)       //比较两个对象是否相等
    {
        return this.real==c.real && this.im==c.im;
    } 
    
    public String toString() 
    {
        return "("+this.real+"+"+this.im+"i)";
    }
    
    public void add(Complex c)             //两个对象相加
    {                                      //改变当前对象,没有返回新对象
        this.real += c.real;
        this.im += c.im;
    }
    
    public Complex plus(Complex c)         //两个对象相加,与add()方法参数一样不能重载
    {                                      //返回新创建对象,没有改变当前对象
        return new Complex(this.real+c.real, this.im+c.im);
    }
    
    public void subtract(Complex c)        //两个对象相减
    {                                      //改变当前对象,没有返回新对象
        this.real -= c.real;
        this.im -= c.im;
    }
    
    public Complex minus(Complex c)        //两个对象相减,与subtract()方法参数一样不能重载
    {                                      //返回新创建的对象,没有改变当前对象
        return new Complex(this.real-c.real, this.im-c.im);
    }
}


class Complex__ex
{
    public static void main(String args[])
    {
        Complex a = new Complex(1,2);
        Complex b = new Complex(3,5);
        Complex c = a.plus(b);             //返回新创建对象
        System.out.println(a+" + "+b+" = "+c);
    } 
}

/*
程序运行结果如下:
(1.0+2.0i) + (3.0+5.0i) = (40.0+7.0i)

*/


实现矩阵的加法

import java.util.Random;
public class Matrix
{private int mx[][],m,n;
  public Matrix(int r,int c)
 { m=r;
   n=c;
   mx=new int[m][n];
   iniMatrix();}
 public Matrix()
  {m=3;
    n=3;
   mx=new int[3][3];
  iniMatrix();}
public void iniMatrix()
  {int i,j;
    Random r=new Random();
     for(i=0;i<=m-1;i++)
         for(j=0;j<=n-1;j++)
          mx[i][j]=r.nextInt(100);
  //mx[i][j]=(int)(Math.random()*100);
  }
public Matrix tranMatrix()
{int i,j;
  Matrix mt=new Matrix(n,m);
  for(i=0;i<=n-1;i++)
     for(j=0;j<=m-1;j++)
          mt.mx[i][j]=mx[j][i];
  return mt;
  }
 public  void printMatrix()
{int i,j;
  for(i=0;i<=m-1;i++)
    { for(j=0;j<=n-1;j++)
         System.out.print("   "+mx[i][j]);
          System.out.println();}
      }
public void addMatrix(Matrix b)
{int i,j;
  for(i=0;i<=m-1;i++)
     for(j=0;j<=n-1;j++)
        mx[i][j]=mx[i][j]+b.mx[i][j];  }
public static void main(String args[])
{Matrix ma=new Matrix(4,3);
 Matrix mb=new Matrix(4,3);
 Matrix mc=new Matrix(3,4);
System.out.println("The  matrix_A:");
ma.printMatrix();
System.out.println("The  matrix_B:");
mb.printMatrix();
System.out.println("Matrix_A + Matrix_B:");
ma.addMatrix(mb);
 ma.printMatrix();
System.out.println("Transpose Matrix_B:");
 mc=mb.tranMatrix();
 mc.printMatrix();
}}

创建顺序表:

//4、输入一组数,以-1结束;并输出。
import java.util.Scanner; //使用输入语句必须导入此类
class Test1{//class类似struct,其中可以包含数据和方法
   final int Maxn=100;
   int[] a; //定义数组变量,注意,并未创建数组对象。
   int len;
   void input(){//实现向数组中输入一组数,以-1结束。输入的数量存入len中
      //注:由于a和len定义在input之外,因此,可以直接使用。
         /*c语言版
         int x,i; 
	   scanf("&d",&x);  i=0;
	   while(x!=-1){a[i]=x; i++;  scanf("&d",&x);}
	   len=i;
	   */
         int x,i; i=0;
         //注意1:必须先创建数组对象,才能向数组中添加数据
         a=new int[Maxn]; //创建包含100个元素的数组对象。// int[] a=new int [100]; //注意,这里用的是方括号
         Scanner sc=new Scanner(System.in); //暂记:构造Scanner对象的固定格式,其中System.in表示标准输入设备
	   System.out.print("请输入一组数,以-1结束:\n");
	   x=sc.nextInt(); //scanf("&d",&x);
	   while(x!=-1){ a[i]=x; i++;  x=sc.nextInt(); }
	   len=i;
   }
   void show(){//输出数组a中的有效数据
   	   for(int i=0; i<len; i++)
   	   	   System.out.print(a[i]+" "); //任何数据都可以和字符串相加(即字符串的连接),相加后变成字符串
   }
}
class App{
   public static void main(String[] x){
      //必须先造对象,然后才能调用方法
      Test1 t=new Test1(); //创建一个对象
      t.input();   t.show();
   }
}
/*本示例掌握以下内容:
	1、class 可以包含数据,如Test1中的len、数组a,这些变量在该类中可视为全局变量,即a、len可以直接在input()、show()等方法中使用;
	2、数组变量必须先用new 造对象,然后才能向其中填写数据。如a=new int[100]; 或是a=new int[x]; //x是变量
	3、使用Scanner输入的步骤:(1)先导入,即import java.util.Scanner; 
	  (2)创建Scanner对象,即 Scanner sc=new Scanner(System.in);
	  (3)借助对象读取数据,如sc.nextInt(); //注意,nextInt()是Scanner类提供的方法/函数。
	*/


理解类和对象:汽车类的设计
假设某赛车游戏中,汽车涉及如下内容:车主、品牌、颜色,能够进行启动、前进、后退、停止、熄火等动作,并要求,若汽车已经启动,就不能重复启动;若汽车处于熄火状态,不能执行除启动外的其它动作。另外,要能够直接打印出汽车对象的信息。请完成汽车类的设计,其中各项动作给出相关信息提示即可。
【目的】(1)新增三个知识点:String型、构造函数、toString()方法;(2)初步理解类应如何设计,进一步理解类由成员组成;(3)初步理解类、对象的基本含义,以及二者间的关系。


class Car{
     String owner,brand,color;//车主、品牌、颜色
     boolean isActive=false; //标记汽车是否启动,boolean型只有两个值:true和false
     Car(String o, String b, String c){ owner=o; brand=b; color=c; } //构造函数
     /*构造函数的特点:1、与类名相同;2、不能用return返回一个值,也不能有任何返回类型(包含void)
     	    换言之,无返回类型,实际上,就是默认只能返回该类名代表的类型
     	    3、构造函数的作用:对属性进行初始化
     	 */
     void start(){ 
     	   if( isActive==true ) {System.out.println("汽车不能重复启动!");return; } //若已经启动,就结束
      	   isActive=true; System.out.println("汽车启动!");
     }
     void go(){ 
     	   if( isActive==false ) {System.out.println("汽车未启动,不能前进!");return;  }
     	   System.out.println("汽车前进!");
     }
     void stop(){ 
     	   if( isActive==false ) {System.out.println("汽车未启动,不能熄火!");return;  }
          isActive=false; System.out.println("汽车熄火!");
     }
     public String toString(){//注意:必须有public、返回必须是String型、必须无参
     	  //书写此函数后,可直接打印对象
     	 //return "车主:"+owner+" 品牌:"+brand+" 颜色:"+color;
     	  return " 品牌:"+brand+" 颜色:"+color;
     	  //此函数的功能:会被System.out.print()在【打印对象时】自动调用;
     }
}
class App{
    public static void main(String[] x){
       Car c=new Car("张三","奇瑞","黑色");
       Car c1=new Car(); //此句编译错,即有若类中定义构造函数,系统将不再补充任何构造函数
       System.out.print(c);
       c.go();  c.stop();  c.start(); c.stop();
     }
}
/*总结:1、类=数据+操作,例如Car中有数据/属性:颜色、品牌等;有操作go()、start()等类中的属性可以在该类的方法中直接使用,如go()可直接使用isActive;
2、类和对象的关系:类就是对象的设计图纸;对象就是基于图纸产生的实体。	          类比 Car 类,相当于图纸,图纸不能前进、熄火等,即Car.go()、Car.stop()是错误的对象是可以执行动作的,如c.go(); 等因此,必须先创建对象(即new Car(...)),然后才能执行该对象关联的方法;
3、构造函数,特点:与类同名,不能有返回类型,且不能用return返回值       注:这点和普通函数不同另外,若类中【未定义】构造函数,系统将自动补充一个默认的无参构造函数;若类中【已经定义】构造函数,系统就不在补充任何构造函数;
 4、public String toString(),这个函数会被System.out.print()在【打印对象时】自动调用;若无参函数,打印对象将会是乱码。
	*/
posted @ 2020-11-01 17:15  Zeker62  阅读(84)  评论(0编辑  收藏  举报