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()在【打印对象时】自动调用;若无参函数,打印对象将会是乱码。
*/
本文来自博客园,作者:{Zeker62},转载请注明原文链接:https://www.cnblogs.com/Zeker62/p/15046309.html