1.实验目的
(1)掌握Java中类和对象的基本知识。
(2)理解Java中的继承(类,子类,接口)和多态机制。
(3)掌握Java中this、super及访问限定符和特征限定符的用法。
(4)应用Java的包的文件组织方式管理代码。
2.实验要求
在Eclipse下创建Practice1项目,对未有包名要求的题目统一按照实验题名建包,然后将本题源代码放在同一包下。对有包名要求的题目按照要求建包。作业提交时将Practice1项目下src文件包中的所有源码文件提交至码云oop_one项目代码仓库中。
3.实验题目
Exer1: 创建Person类,并设置name,sex及age三个private属性,设置无参构造方法和带参数的构造方法;设置setName(),setSex(),setAge()方法给三个属性赋值,并用getName(),getSex(),getAge()方法获取三个属性的值;重写父类(Object)的toString()方法,实现Person类对象的属性输出,注意toString()方法返回值类型为String。
基本要求:
- 设计CreatPerson类,使用无参构造方法创建Person类对象,用set***和get***方法完成属性初始化和输出。
- 使用有参构造方法创建Person类对象,并调用toString()方法完成属性输出。
package first;
class Person{
private String name;
private String sex;
private int age;
Person(){};
public void setName(String name1){
name=name1;
}
public void setSex(String sex1){
sex=sex1;
}
public void setAge(int age1){
age=age1;
}
public String toString(){
return "姓名 "+name+",性别 "+sex+",年龄 "+age;
}
Person(String name,String sex,int age){
this.name = name;
this.sex = sex;
this.age = age;
}
}
class CreatePerson{
CreatePerson(){
Person p1 = new Person();
p1.setName("Jarry");
p1.setSex("女");
p1.setAge(17);
System.out.println(p1.toString());
}
}
public class Example {
public static void main(String[] args) {
Person p1;
p1 = new Person();
p1.setName("Tom");
p1.setSex("男");
p1.setAge(17);
System.out.println(p1.toString());
Person p2 = new Person("Belly","女",18);
System.out.println(p2.toString());
CreatePerson p3 = new CreatePerson();
}
}
运行编译,输出结果:
姓名 Tom,性别 男,年龄 17
姓名 Belly,性别 女,年龄 18
姓名 Jarry,性别 女,年龄 17
Exer2: 设计一个用来描述汽车的类Car,使用类的非静态成员变量来表示汽车的车主姓名name、当前的速率speed:
基本要求:
- 创建构造函数为成员变量赋初值。
- 使用类的非静态成员方法来表示改车主姓名changeName操作, 并通过该方法显示修改后的车主名称。
- 使用类的非静态成员方法来表示改变汽车的速率changSpeed操作,并通过该方法显示修改后的车速。
- 使用类的非静态成员方法来表示停车stop操作,并通过该方法显示停车后的车速。
- 创建一个Car类的对象,初始状态时,车主名称是自己的名字,speed=0。
- 分别调用这三个方法,更改车名为朋友的名字,车速为20,停车车速为0,并且得到如下的结果:
package first;
class Car{
String m_name;
int m_speed;
Car(String name,int speed){
m_name = name;
m_speed = speed;
}
void changeName(String name){
m_name = name;
System.out.println("车主为:"+m_name);
}
void changeSpeed(int speed){
m_speed = speed;
System.out.println("当前速度为:"+ m_speed);
}
void stop(){
m_speed = 0;
System.out.println("停车后"+",车速为:"+m_speed);
}
}
public class Example2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Car car = new Car("wx",0);
car.changeSpeed(20);
car.changeName("好友");
car.stop();
}
}
运行编译,输出结果:
当前速度为:20
车主为:好友
停车后,车速为:0
Exer3: 定义人类Human及其子类Child。其中Human具有姓名name、年龄age属性成员,具有无参和有参构造方法Human(String name, int age),其他方法有void walk(){System.out.println(name+“… ”)}和void eat() {System.out.println(name+“爱吃西瓜”)},Child子类还具有schoolName属性成员及其有参构造方法,具有void study() {System.out.println(name+“学习数学”)},且重写父类方法walk()。Human和Child的walk方法走路的方式分别是“稳健的走”和“蹦跳的走”。
基本要求:
- 在子类的构造方法中调用父类的有参构造方法
- 建立测试类,在测试类中完成以下操作
- 创建Human类对象h,调用它的方法walk(),eat()
- 创建Child类对象c,调用方法study(),walk()
- 将对象c的引用赋给h,观察h.walk(),h.eat()。h可以调用study()方法吗?为什么?
- 思考Human中如果没有无参构造函数可以吗?
package first;
class Human{
String name;
int age;
Human(){}
Human(String name,int age){
this.name = name;
this.age = age;
}
void walk() {
System.out.println(name+"稳健的走");
}
public void eat(){
System.out.println(name+"爱吃西瓜");
}
}
class Child extends Human{
String schoolName;
Child(String name,String schoolName,int age){
super(name,age);
schoolName =name;
}
void study(){
System.out.println(name+"学习数学");
}
public void walk(){
System.out.println(name+"蹦跳的走");
}
}
public class Example3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Human h = new Human("张三",30);
Child c = new Child("小丸子","朝阳小学",7);
h = c;
h.walk();
// h.study();
}
}
编译运行,输出结果:
小丸子蹦跳的走
Exer 4: 对象的组合。现有一个Rectangle类,请设计一个柱形类Cuboid。
基本要求:
- 此类具有两个成员变量,(1)Rectangle类型的成员变量rect(长方体以长方形做底)和(2)height(柱形的高)。
- 此类应具有构造方法。
- 此类应具有求体积的方法getVolme()。
- 此类应具有设置和获得底的长度和宽度的方法:getBottomWidth()。
setBottomWidth(),
getBottomLength(),
setBottomLength()。
Rectangle的代码如下:
public class Rectangle {
double width,length;
public void setWidth(double w) {
if(w > 0)
this.width=w;
}
public double getWidth(){
return width;
}
public void setLength (double h) {
if(h > 0)
this.length =h;
}
public double getLength () {
return length;
}
}
作答过程:
package first;
class Rectangle {
double width,length;
public void setWidth(double w) {
if(w > 0)
this.width=w;
}
public double getWidth(){
return width;
}
public void setLength (double h) {
if(h > 0)
this.length =h;
}
public double getLength () {
return length;
}
}
class Cuboid{
Rectangle rect;
double height;
Cuboid(double height){
this.height = height;
}
void setBottom(Rectangle rect) {
this.rect = rect;
}
public double getVolme(){
if (rect == null)
return -1;
else
return rect.length*rect.width*height;
}
public void setBottomWidth(double width){
if(width>0)
rect.setWidth(width);
}
public double getBottomWidth(){
return rect.getWidth();
}
public void setBottomLength(double length){
if(length>0)
rect.setLength(length);
}
public double getBottomLength(){
return rect.getLength();
}
}
public class Example4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Rectangle rect1 = new Rectangle();
rect1.setWidth(3.0);
rect1.setLength(7.0);
Cuboid cuboid = new Cuboid(9.0);
cuboid.rect = rect1;
double area = cuboid.getVolme();
System.out.println("柱体的体积为"+area);
}
}
编译运行,输出结果:
柱体的体积为189.0
Exer 5:设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声。
基本要求:
- 编写抽象类Animal
Animal抽象类有2个抽象方法cry()和getAnimaName(),即要求各种具体的动物给出自己的叫声和动物种类名称。
- 编写模拟器类Simulator
该类有一个playSound(Animal animal)方法,该方法的参数是Animal类型。即参数animal可以调用Animal的子类重写的cry()方法播放具体动物的声音、调用子类重写的getAnimalName()方法显示动物种类的名称。
- 编写Animal类的子类:Dog,Cat类
- 编写主类Application(用户程序)
在主类Application的main方法中至少包含如下代码:
Simulator simulator = new Simulator();
simulator.playSound(new Dog());
simulator.playSound(new Cat());
下图是Simulator、Animal、Dog、Cat的UML图。
package first;
abstract class Animal{
public abstract void cry();
public abstract void getAnimalName();
}
class Simulator{
public void playSound(Animal animal){
animal.cry();
animal.getAnimalName();
}
}
class Dog extends Animal{
public void cry(){
System.out.println("汪汪汪");
}
public void getAnimalName(){
System.out.println("狗");
}
}
class Cat extends Animal{
public void cry(){
System.out.println("喵喵喵");
}
public void getAnimalName(){
System.out.println("猫");
}
}
public class Application {
public static void main(String[] args) {
// TODO Auto-generated method stub
Simulator simulator = new Simulator();
simulator.playSound(new Dog());
simulator.playSound(new Cat());
}
}
编译运行,输出结果:
汪汪汪
狗
喵喵喵
猫
Exer 6: 在edu.nwafu.data 包中编写图形抽象类Shape,包含一个常量PI和一个抽象方法getPerimeter()。Circle类和Rectangle类继承了抽象类Shape,Circle类包含一个属性radius,实现抽象方法getPerimeter(),覆盖方法toString()实现自定义圆的输出信息:半径为**的圆周长是:**;Rectangle类包含了两个属性length、width,实现抽象方法getPerimeter(),覆盖方法toString()实现自定义矩形的输出信息:长为**宽为**的矩形周长是:**。
在edu.nwafu包中编写ShapeTest类是测试类,设计public void addOne(Shape shape)方法,实现如果传入的是Circle对象,则半径加1,如果传入的是Rectangle对象,长和宽分别加1; main()方法中要求构造Circle和Rectangle类的对象,并对toString和addOne方法进行测试。
(提示:instanceof运算符可以判断一个对象是否为某个类的实例)
Shape.java:
package edu.nwafu.data;
public abstract class Shape {
final double PI = 3.1415926;
abstract double getPerimeter();
}
Circle.java:
package edu.nwafu.data;
public class Circle extends Shape{
public double radius;
public Circle(double r){
radius = r;
}
public double getPerimeter(){
return 2*PI*radius;
}
public String toString(){
return "半径为"+radius+"的圆周长为 "+getPerimeter();
}
}
Rectangle.java:
package edu.nwafu.data;
public class Rectangle extends Shape{
public double length;
public double width;
public Rectangle(double l,double w){
length = l;
width = w;
}
public double getPerimeter(){
return 2*(length+width);
}
public String toString(){
return "长为"+length+",宽为"+width+"的矩形周长为"+getPerimeter();
}
}
Example6.java,测试类:
package edu.nwafu;
import edu.nwafu.data.*;
class ShapeTest{
public void addOne(Shape shape){
if (shape instanceof Circle) {
Circle circle=(Circle)shape;
circle.radius= circle.radius + 1;
System.out.println("加法之后圆的半径为"+circle.radius);
}
else if(shape instanceof Rectangle) {
Rectangle rect = (Rectangle)shape;
rect.length += 1;
rect.width +=1;
System.out.println("加法之后矩形的长为"+rect.length+",矩形的宽为"+rect.width);
}
}
}
public class Example6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Circle c = new Circle(2);
Rectangle rect = new Rectangle(5,4);
Shape shape = new Circle(6);
Shape shape1 = new Rectangle(7,6);
System.out.println(c.toString());
System.out.println(rect.toString());
ShapeTest test = new ShapeTest();
test.addOne(shape);
test.addOne(shape1);
}
}
编译运行,输出结果:
半径为2.0的圆周长为 12.5663704
长为5.0,宽为4.0的矩形周长为18.0
加法之后圆的半径为7.0
加法之后矩形的长为8.0,矩形的宽为7.0
Exer 7 实现一个名为Person的类和它的子类Employee, Manager是Employee的子类,设计一个接口Add用于涨工资,接口中有一个抽象方法addVage()。普通员工一次能涨10%,经理能涨20%。
具体要求如下:
- Person类中的属性有:姓名name(String类型),地址address(String类型)并写出该类的构造方法;
- Employee类中的属性有:工号ID(String型),工资vage(double类型),工龄(int型),写出该类的构造方法;
- Manager类中的属性有:级别level(String类型),写出该类的构造方法;
- 编写一个测试类,产生一个员工和一个经理并输出其具有的信息, 之后给这两个人增加工资,然后再次输出信息。
Add.java
package Exer7;
public interface Add {
void addVage();
}
Person.java
package Exer7;
public abstract class Person {
String name;
String address;
Person(String n,String a){
name = n;
address = a;
}
}
Employee.java
package Exer7;
public class Employee extends Person implements Add {
String ID;
double vage;
int age;
Employee(String name, String address,String id,double vage,int age){
super(name,address);
ID = id;
this.vage = vage;
this.age = age;
}
public void addVage() {
vage = vage + 0.1*vage;
}
//输出信息
public String toString() {
return "name:" + name+" address:"+address +" id:"+ID+" vage:"+vage
+" workAge:"+age;
}
}
Manager.java
package Exer7;
public class Manager extends Employee implements Add{
String level;
Manager(String name,String address,String ID,double vage,int age,String level){
super(name,address,ID,vage,age);
this.level = level;
}
public void addVage() {
vage = vage + 0.2*vage;
}
public String toString() {
return "name:" + name+" address:"+address +" id:"+ID+" vage:"+vage
+" workAge:"+age+" level:"+level;
}
}
测试类Exer7.java
package Exer7;
public class Exer7 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Employee employee = new Employee("zhangsan","beijing","001",1000.0,2);
Manager manager = new Manager("liuchan","beijing","002",10000.0,5,"D");
System.out.println(employee.toString());
employee.addVage();
System.out.println(employee.toString());
System.out.println(manager.toString());
manager.addVage();
System.out.println(manager.toString());
}
}
编译运行,输出结果:
name:zhangsan address:beijing id:001 vage:1000.0 workAge:2
name:zhangsan address:beijing id:001 vage:1100.0 workAge:2
name:liuchan address:beijing id:002 vage:10000.0 workAge:5 level:D
name:liuchan address:beijing id:002 vage:12000.0 workAge:5 level:D