当前位置:网站首页>实验六 继承和多态

实验六 继承和多态

2022-07-06 09:22:00 文文喜欢郭子吖

实验六  继承和多态

实验目的

1. 掌握接口的使用方法

2. 掌握子类的继承性、子类对象的创建过程

3. 掌握成员变量的继承与隐藏、方法的继承与重写

实验学时 6学时

实验内容

1. 编写程序为公交车的老人卡、学生卡和普通市民卡提供收费功能。将充值、收费功能提取,定义在一个接口中,然后被这三种卡类实现。最后编写一个测试类,用于测试公交车三类卡的刷卡操作。

package code61;

public interface Buscard {  //定义接口Bus card

void recharge();

void charge();

}

package code61;

public class Oldpeople implements Buscard {  //实现接口

public void recharge() {

System.out.println("老年卡充值成功!");  //重写接口的充值方法

}

public void charge() {

System.out.println("使用老年卡,扣一元!");  //重写接口的收费方法

}

}

package code61;

public class People implements Buscard {  //实现接口

public void recharge() {

System.out.println("普通市民卡充值成功!");  //重写接口充值方法

}

public void charge() {

System.out.println("使用普通市民卡,扣2元!");  //重写接口收费方法

}

}

package code61;

public class Student implements Buscard {  //实现接口

public void recharge() {

System.out.println("学生卡充值成功!");  //重写接口充值方法

}

public void charge() {

System.out.println("使用学生卡,扣1.5元!");  //重写接口收费方法

}

}

package code61;

public class Test {

public static void main(String[] args) {

// TODO 自动生成的方法存根

Oldpeople O = new Oldpeople();

O.recharge();

O.charge();  //定义老年卡对象,并调用充值、收费方法

Student S = new Student();

S.recharge();

S.charge();  //定义学生卡对象,并调用充值、收费方法

People P = new People();

P.recharge();

P.charge();  //定义市民卡对象,并调用充值、收费方法

}

}

2.设计四个类、一个接口,类之间的关系如下:

 

在类App中使用Compute、Circle、Rectangle类,在Compute类中使用Shape接口(Shape对象作为computeArea方法的形式参数),Circle、Rectangle类实现接口Shape,重写area()方法。图中“+”的表示public,“-”的表示private,框图中上面一栏是类或接口的名称,中间一栏是属性,下面一栏是方法。

在App类的main()中:

  1. 创建一个Compute类对象、一个Circle类对象和一个Rectangle类对象。
  2. 调用Compute对象的computeArea方法(实际参数为Circle对象)计算圆的面积。
  3. 调用Compute对象的computeArea方法(实际参数为Rectangle对象)计算矩形面积。

package code62;

public class App {

public static void main(String[] args) {

// TODO 自动生成的方法存根

Compute a = new Compute();

Circle b = new Circle(2);

Rectangle c = new Rectangle(2,2);

System.out.println("圆的面积为:"+a.computArea(b));  //调用Compute对象的computeArea方法,实参为Circle对象

System.out.println("矩形面积为:"+a.computArea(c));  //调用Compute对象的computeArea方法,实参为Rectangle对象

}

}

package code62;

public class Circle implements Shape {  //实现接口

private int radius;

public Circle(int radius) {

this.radius=radius;

}

public double area() {

return PI*radius*radius;  //重写接口的area方法,求圆的面积

}

}

package code62;

public class Compute {

public double computArea(Shape s) {  //Shape对象作为该方法的形式参数

return s.area();

}

}

package code62;

public class Rectangle implements Shape {  //实现接口

private int width;

private int height;

public Rectangle(int width,int height) {

this.width=width;

this.height=height;

}

public double area() {

return width*height;  //重写接口的area方法,求矩形面积

}

}

package code62;

public interface Shape {  //定义接口

double PI=3.14;

double area();

}

3. 普通门和报警门。

(1)定义一个接口Alarm(报警),含有一个报警方法void alarm( );

(2)定义一个类Door(普通门),Door类有一个私有属性name(品牌);有4个公有方法getName、setName、open(开门)、close(关门);open、close方法的功能由自己确定。

(3)定义一个类AlarmDoor(报警门),继承Door类,实现接口Alarm,重写接口中的抽象方法alarm(方法的功能由自己确定)。

(3)编写一个测试类DoorTest,在main方法中,给出多种型号的报警门和普通门,调用开门、关门、报警等动作。

package code63;

public interface Alarm {  //定义接口

void alarm();

}

package code63;

public class AlarmDoor extends Door implements Alarm {  //继承Door类,实现接口Alarm

public void alarm() {

System.out.println(this.getName()+"嘟嘟嘟!警报响起!");  //重写接口中的抽象方法

}

}

package code63;

public class Door {

private String name;  //私有属性name

public String getName() {  

return name;

}

public void setName(String name) {

this.name=name;

}

public void open() {

System.out.println(this.name+"门开了!");

}

public void close() {

System.out.println(this.name+"门关了!");

}

}

package code63;

public class DoorTest {

public static void main(String[] args) {

// TODO 自动生成的方法存根

AlarmDoor a1 = new AlarmDoor();

a1.setName("低级报警门!");

a1.open();

a1.alarm();  //创建对象a1,并调用各方法

AlarmDoor a2 = new AlarmDoor();

a2.setName("高级报警门!!!");

a2.open();

a2.close();

a2.alarm();  //创建对象a2,并调用各方法

AlarmDoor a3 = new AlarmDoor();

a3.setName("普通门.");

a3.open();

a3.close();  //创建对象a3,并调用各方法

}

}

4.  设计五个类(测试类、计算机类、手机类、充电器类、U盘类)、一个接口(Usb接口),各类之间的关系如下:

 

(1)在UsbTest类的main方法中,创建一个Xiaomi手机对象、一个小米CDQ012M充电器对象、一台联想电脑、一个Kingston U盘对象。然后将充电器插入手机充电,将U盘插入计算机。

(2)在Mobile类的InsertUsb方法中,连接Usb。

(3)在Computer类的InsertUsb方法中,连接Usb。

(4)在Charger类的connect方法中,输出“已连接充电器,正在充电...”。

(5)在UDisk类的connect方法中,输出“已连接U盘器,正在读取数据...”。

package code64;

public class Charger implements Usb {

private String brand;

public Charger(String brand) {

this.brand=brand;

}

public void connect() {

System.out.println("已连接充电器"+this.brand+",正在充电...");  //重写接口的connect方法

}

}

package code64;

public class Computer {

private String brand;

public Computer(String brand) {

this.brand=brand;

}

public void insertUsb(Usb device) {

System.out.println(this.brand);

device.connect();  //构造连接方法

}

}

package code64;

public class Moblie {

private String brand;

public void Moblie(String brand) {

this.brand=brand;

}

public void insertUsb(Usb device) {

System.out.println(this.brand);

device.connect();  //构造连接方法

}

}

package code64;

public class UDisk implements Usb {

private String brand;

public UDisk(String brand) {

this.brand=brand;

}

public void connect() {

System.out.println("已连接U盘器"+this.brand+",正在读取数据...");  //重写接口的connect方法

}

}

package code64;

public interface Usb {  //定义接口

void connect();

}

package code64;

public class UsbTest {

public static void main(String[] args) {

// TODO 自动生成的方法存根

Moblie a = new Moblie();

a.Moblie("Xiaomi");  //创建手机对象

Charger b = new Charger("小米CDQ012M");  //创建充电器对象

Computer c = new Computer("联想");  //创建电脑对象

UDisk d = new UDisk("Kingston");  //创建U盘对象

a.insertUsb(b);  //充电器插入手机

c.insertUsb(d);  //U盘插入计算机

}

}

5. 设计一个武器系统,要求如下:

(1)定义一个弹药类Bullet,有一个弹药名称属性name。设计一个构造方法及set、get方法。

(2)定义一个可装载弹药的接口Loadable,该接口有一个装载的抽象方法load()。

(3)定义一个可发射弹药的接口Launchable,该接口有一个发射的抽象方法launch()。

(4)定义一个武器类Weapon,既可以装弹,也可以发射。

    武器类有一个属性name(武器名称)、可使用的弹药bullet(Bullet对象)以及对应的get、set方法。

重写load方法,在方法中输出装载的弹药。

重写launch方法,在方法中输出发射的弹药。

(4)定义3个普通武器类:Tank、Flighter、WarShip都继承武器类Weapon。 每个普通武器类都有一个带一个参数name的构造方法,在构造方法中创建弹药对象。

坦克Tank使用的弹药是炮弹,战斗机Flighter使用的弹药是导弹,舰艇WarShip使用的弹药是鱼雷。

(5)定义一个类Army,代表一支军队,包括:。

1) 属性:ArrayList<Weapon> weapon用来存放军队装备的各种武器,自己查找集合类ArrayList的用法和泛型的知识点;

2) 获取军队的拥有的武器数量方法getNum;

3)添置武器的方法addWeapon

4) 让所有武器都装载弹药的方法loadAll;

5)让所有武器都发起攻击的方法luanchAll。

(6)编写一个测试类,在main方法中:

1)建立一支强大的军队;

2)添置各种型号武器,包括坦克、战机、舰艇。

3)输出军队拥有的武器数量;

4)让所有的武器都装上弹药;

5)让所有的武器都发射。

 

package code65;

import java.util.ArrayList;

public class Army {

ArrayList<Weapon> weapon;

public Army() {

weapon = new ArrayList<Weapon>();  //存放军队装备的各种武器

}

public int getNum() {

return weapon.size();  //获取军队的拥有的武器数量

}

public void addWeapon(Weapon weapon) {

this.weapon.add(weapon);  //添置武器

}

public void loadAll() {

System.out.println("所有武器准备装弹药...");

int a=1;

for(Weapon weapon:weapon) {

System.out.print(a+":"+weapon.getName());

weapon.load();

a++;  //让所有武器都装载弹药

}

}

public void luanchAll() {

System.out.println("所有武器准备战斗...");

int a=1;

for(Weapon weapon:weapon) {

System.out.print(a+":"+weapon.getName());

weapon.launch();

a++;  //让所有武器都发射弹药

}

}

}

package code65;

public class Bullet {

private String name;

public Bullet(String name) {  //构造方法

this.name=name;

}

public void setName(String name) {

this.name=name;

}

public String getName() {

return name;

}

}

package code65;

public class Flighter extends Weapon {  //继承武器类

public Flighter(String name) {

setName(name);

Bullet bullet = new Bullet("导弹");  //创建导弹对象

setBullet(bullet);

}

}

package code65;

public interface Launchable {  //定义一个可发射弹药的接口

void launch();

}

package code65;

public interface Loadable {  //定义一个可装载弹药的接口

void load();

}

package code65;

public class Tank extends Weapon {  //继承武器类

public Tank(String name) {

setName(name);

Bullet bullet = new Bullet("炮弹");  //创建炮弹对象

setBullet(bullet);

}

}

package code65;

public class WarShip extends Weapon {  //继承武器类

public WarShip(String name) {

setName(name);

Bullet bullet = new Bullet("鱼雷");  //创建鱼雷对象

setBullet(bullet);

}

}

package code65;

public class Weapon implements Loadable,Launchable {  //实现两接口

private String name;

private Bullet bullet;

public String getName() {

return name;

}

public void setName(String name) {

this.name=name;

}

public Bullet getBullet() {

return bullet;

}

public void setBullet(Bullet bullet) {

this.bullet=bullet;

}

public void load() {

System.out.println("装载"+this.bullet.getName());  //重写接口的装载方法

}

public void launch() {

System.out.println("发射"+this.bullet.getName());  //重写接口的发射方法

}

}

package code65;

public class Test {

public static void main(String[] args) {

// TODO 自动生成的方法存根

Tank a1 = new Tank("99坦克 ");

Flighter a2 = new Flighter("歼20 ");

WarShip a3 = new WarShip("武汉舰 ");

WarShip a4 = new WarShip("芜湖舰 ");

Flighter a5 = new Flighter("歼31 ");

Flighter a6 = new Flighter("F35 ");  //建立军队

Army a = new Army();

a.addWeapon(a1);

a.addWeapon(a2);

a.addWeapon(a3);

a.addWeapon(a4);

a.addWeapon(a5);

a.addWeapon(a6);  //添置各种武器

System.out.println("军队装备的武器数量:"+a.getNum());

a.loadAll();  //让所有武器装上弹药

a.luanchAll();  //让所有武器都发射

}

}

6. 设计五个类,类之间的关系如下

 

在类App中使用Paint、Rectangle、Circle、Rabit类,在paint类中使用AsciiArt抽象类(AsciiArt对象作为setArt方法的参数),Rectangle、Circle、Rabit类继承抽象类AsciiArt,并重写draw()方法。

具体设计步骤:

  1. App类的main( )

1)创建一个Paint对象paint

2)显示作品列表

========作品列表=======

  1. 矩形
  2. 小兔子

======================

请选择:

3) 根据选择,显示不同的作品

    ① 画矩形

        a.创建一个Rectangle对象rect。

b.调用paint的setArt方法,将rect设置为paint对象要显示的作品。

c.调用对象paint的draw方法显示作品。

②画圆

a.创建一个Circle对象c。

b.调用paint的setArt方法,将c设置为paint对象要显示的作品。

c.调用对象paint的draw方法显示作品。

    ③画小兔子

        a.创建一个Rabit对象rabit。

b.调用paint的setArt方法,将rabit设置为paint对象要显示的作品。

c.调用对象paint的draw方法显示作品。

  1. Paint类中的draw( )

①显示作品名、作者。

②调用成员变量art的draw方法显示作品。

  1. Rectangle类中的draw( )

输出width行height列个“*”。

  1. Circle类中的draw( )

输出用“*”组成的圆。

  1. Rabit类中的draw( )

输出可爱的小兔。

package code66;

import java.util.Scanner;

public class App {

public static void main(String[] args) {

// TODO 自动生成的方法存根

Scanner in=new Scanner(System.in);

System.out.println("========作品列表=======");

System.out.println("1.矩形");

System.out.println("2.圆");

System.out.println("3.小兔子");

System.out.println("======================");

System.out.println("请选择:");

int select=in.nextInt();

Paint paint = new Paint();

switch(select){  //根据选择,显示不同作品

case 1:

Rectangle rect = new Rectangle("矩形","张三",3,8);

paint.setArt(rect);  //调用方法,将rect设置为paint对象要显示的作品

paint.draw();  //调用draw方法

break;

case 2:

Circle c = new Circle("圆形","小丫",4);

paint.setArt(c);  //调用方法,将c设置为paint对象要显示的作品

paint.draw();  //调用draw方法

break;

case 3:

Rabit rabit = new Rabit("兔子","李四");

paint.setArt(rabit);  //调用方法,将rabit设置为paint对象要显示的作品

paint.draw();  调用draw方法

break;

}

}

}

package code66;

public abstract class AssciiArt {  //定义一个抽象类

private String title;  //作品名

private String author;  //作者名

public AssciiArt(String title,String author) {

this.title=title;

this.author=author;

}

abstract void draw();  //抽象画图方法

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title=title;

}

public String getAuthor() {

return author;

}

public void setAuthor(String author) {

this.author=author;

}

}

package code66;

public class Circle extends AssciiArt {  //继承AssciiArt类

private int radius;

public Circle(String title,String author,int radius) {

super(title,author);  //访问父类中被覆盖的成员

this.radius=radius;

}

public void draw() {  //重写画图方法

int d=2*radius;

for(int y=0;y<=d;y++) {

for(int x=0;x<=d;x++) {

if((x-radius)*(x-radius)+(y-radius)*(y-radius)<=radius*radius)

System.out.print("**");

else

System.out.print("  ");

}

System.out.println();  //输出用"*"组成的圆

}

}

}

package code66;

public class Paint {

private AssciiArt art;

public void setArt(AssciiArt art) {  //AsciiArt对象作为setArt方法的参数

this.art=art;

}

public void draw() {

System.out.println("作品:"+this.art.getTitle());

System.out.println("作者:"+this.art.getAuthor());

this.art.draw();  //调用art的draw方法显示作品

}

}

package code66;

public class Rabit extends AssciiArt {  //继承AssciiArt类

public Rabit(String title,String author) {

super(title,author);  //访问父类中被覆盖的成员

}

public void draw() {  //重写画图方法

System.out.println("/)/)");

System.out.println("(- -) )o");

System.out.println("  || ||");  //画出小兔子

}

}

package code66;

public class Rectangle extends AssciiArt {  //继承AssciiArt类

private int width;

private int height;

public Rectangle(String title,String author,int width,int height) {

super(title,author);  //访问父类中被覆盖的成员

this.width=width;

this.height=height;

}

public void draw() {  //重写画图方法

for(int a=0;a<width;a++) {

for(int b=0;b<height;b++) {

System.out.print("*");  //输出width行height列个"*"组成的矩形

}

System.out.println();

}

}

}

实验小结

  1. 类的继承是实现代码复用最有效的方法;
  2. Java只支持单继承,即只能有一个父类,但类之间的继承可以传递;
  3. 继承格式:class 子类名 extends 父类名;
  4. 关键字super可以用来在子类中访问父类中被覆盖的成员;
  5. 关键字abstract修饰的类为抽象类,其更多是作为其他类的父类,其中的抽象方法必须在子类中具体实现;
  6. 接口定义格式:【修饰符】interface接口名;
  7. 接口中的所有方法都是抽象的,必须在实现该接口的子类中重写所有的抽象方法;
  8. 接口实现格式:class 类名 implements 接口名;
  9. 被实现的接口可以有多个,之间有逗号隔开;
  10. 另外还要去掌握ArrayList的使用方法。
原网站

版权声明
本文为[文文喜欢郭子吖]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_63689135/article/details/124719921