当前位置:网站首页>实验六 继承和多态
实验六 继承和多态
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()中:
- 创建一个Compute类对象、一个Circle类对象和一个Rectangle类对象。
- 调用Compute对象的computeArea方法(实际参数为Circle对象)计算圆的面积。
- 调用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()方法。
具体设计步骤:
- App类的main( )
1)创建一个Paint对象paint
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方法显示作品。
- Paint类中的draw( )
①显示作品名、作者。
②调用成员变量art的draw方法显示作品。
- Rectangle类中的draw( )
输出width行height列个“*”。
- Circle类中的draw( )
输出用“*”组成的圆。
- 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();
}
}
}
实验小结
- 类的继承是实现代码复用最有效的方法;
- Java只支持单继承,即只能有一个父类,但类之间的继承可以传递;
- 继承格式:class 子类名 extends 父类名;
- 关键字super可以用来在子类中访问父类中被覆盖的成员;
- 关键字abstract修饰的类为抽象类,其更多是作为其他类的父类,其中的抽象方法必须在子类中具体实现;
- 接口定义格式:【修饰符】interface接口名;
- 接口中的所有方法都是抽象的,必须在实现该接口的子类中重写所有的抽象方法;
- 接口实现格式:class 类名 implements 接口名;
- 被实现的接口可以有多个,之间有逗号隔开;
- 另外还要去掌握ArrayList的使用方法。
边栏推荐
- Redis实现分布式锁原理详解
- Custom RPC project - frequently asked questions and explanations (Registration Center)
- MySQL锁总结(全面简洁 + 图文详解)
- Cookie和Session的区别
- 20220211-CTF-MISC-006-pure_ Color (use of stegsolve tool) -007 Aesop_ Secret (AES decryption)
- C language Getting Started Guide
- A piece of music composed by buzzer (Chengdu)
- Inaki Ading
- 关于双亲委派机制和类加载的过程
- [中国近代史] 第六章测验
猜你喜欢
The latest tank battle 2022 - Notes on the whole development -2
4. Binary search
Thoroughly understand LRU algorithm - explain 146 questions in detail and eliminate LRU cache in redis
Difference and understanding between detected and non detected anomalies
. Net6: develop modern 3D industrial software based on WPF (2)
C语言入门指南
Programme de jeu de cartes - confrontation homme - machine
2. C language matrix multiplication
Leetcode.3 无重复字符的最长子串——超过100%的解法
Principles, advantages and disadvantages of two persistence mechanisms RDB and AOF of redis
随机推荐
SRC挖掘思路及方法
TypeScript快速入门
扑克牌游戏程序——人机对抗
MySQL lock summary (comprehensive and concise + graphic explanation)
【九阳神功】2016复旦大学应用统计真题+解析
【黑马早报】上海市监局回应钟薛高烧不化;麦趣尔承认两批次纯牛奶不合格;微信内测一个手机可注册俩号;度小满回应存款变理财产品...
5. Download and use of MSDN
Redis cache obsolescence strategy
甲、乙机之间采用方式 1 双向串行通信,具体要求如下: (1)甲机的 k1 按键可通过串行口控制乙机的 LEDI 点亮、LED2 灭,甲机的 k2 按键控制 乙机的 LED1
It's never too late to start. The tramp transformation programmer has an annual salary of more than 700000 yuan
Principles, advantages and disadvantages of two persistence mechanisms RDB and AOF of redis
The difference between overloading and rewriting
View UI plus releases version 1.1.0, supports SSR, supports nuxt, and adds TS declaration files
FAQs and answers to the imitation Niuke technology blog project (I)
About the parental delegation mechanism and the process of class loading
The difference between cookies and sessions
3.猜数字游戏
C language to achieve mine sweeping game (full version)
The difference between abstract classes and interfaces
这次,彻底搞清楚MySQL索引