实验3 类的多态性和接口
一、实验目的
理解面向对象的多态性。理解接口和实现接口的类的关系,掌握一个类实现多个接口的声明和使用方法。
二、实验内容
1.程序理解:
接口的应用
//接口的应用
//定义一个PCI接口:
interface PCI {
void start(); // 定义抽象方法start()
void stop(); // 定义抽象方法stop()
}
// 定义 NetworkCard类实现PCI接口
class NetworkCard implements PCI {
// 实现start()方法
public void start() {
System.out.println("send...");
}
// 实现stop()方法
public void stop() {
System.out.println("Network stop.");
}
}
// 定义 SoundCard类实现PCI接口
class SoundCard implements PCI {
// 实现start()方法
public void start() {
System.out.println("Du Du...");
}
// 实现stop()方法
public void stop() {
System.out.println("Sound stop.");
}
}
// 定义MainBoard类
// 将子类对象作为PCI参数传进来:
class MainBoard {
// 在这里传了一个接口参数p
// 定义一个userPCICard()方法,接收PCI类型的参数
public void userPCICard(PCI p) {
// 正是因为实现了PCI接口里面的方法,才能将对象传给这个引用变量
p.start(); // 调用传入对象的start()方法
p.stop(); // 调用传入对象的stop()方法
}
}
// 使用接口实现的子类对象
public class Example3 {
public static void main(String[] args) {
MainBoard mb = new MainBoard(); // 创建MainBoard类的实例对象
NetworkCard nc = new NetworkCard(); // 创建NetworkCard类的实例对象nc
mb.userPCICard(nc); // 调用MainBoard对象的userPCICard()的方法,将nc作为参数传入
SoundCard sc = new SoundCard(); // 创建NetworkCard类的实例对象sc
mb.userPCICard(sc); // 调用MainBoard对象的userPCICard()的方法,将sc作为参数传入
}
}
2.编程题:
(1)声明复数类Complex,成员变量包括double类型的实部real和double类型的虚部im,成员方法包括三个重载的构造方法:实部和虚部构造方法Complex(double real, double im);无参构造方法 Complex(),该无参构造方法内部用this(0,0)调用前一个构造方法;只有实数部分的构造方法Complex(double real),该构造方法内部用this(real,0)调用两个参数的构造方法。此外,该复数类的成员方法还包括复数加法、复数减法、字符串描述(重写Object的toString方法,输出a+bi的形式)、相等比较(判断两个复数是否相等,需要重写Object的equals方法)等方法。定义测试类,在main方法中进行相应的测试。(程序1)
(2)定义两个接口Area(声明getArea方法求面积)和Volume(声明getVolume方法求体积),声明球类Globe,实现Area和Volume接口,计算球的表面积和体积。设计测试类,在main方法中进行相应的测试。(程序2)
(3)完成如下所示接口的继承和实现结构,定义测试类,在main方法中进行测试。(接口和类名字可以更改)(程序3)
(4)选做题: 设计一个程序,该程序通过使用父类类型变量引用不同的子类对象,从而实现类型的多态。
三、实验结果和分析
说明:请截图给出各个程序的运行结果,并做必要的分析。
(1)程序1运行结果
(2)程序2运行结果
(3)程序3运行结果
(4)程序4运行结果(如选做)
四、实验源代码
说明:请将各程序的源代码复制粘贴到这里。
(1)程序1源代码
import java.util.Scanner;
//定义复数类Complex
class Complex1 {
double real;
double im;
// 定义实部和虚部构造方法
Complex1(double real, double im) {
this.real = real;
this.im = im;
}
// 无参构造方法
Complex1() {
this(0, 0);
}
// 有实数部分的构造方法
Complex1(double real) {
this(real, 0);
}
// 定义复数加法的方法
public Complex1 add(Complex1 c) {
return new Complex1(this.real + c.real, this.im + c.im);
}
// 复数减法
public Complex1 minus(Complex1 c) {
return new Complex1(this.real - c.real, this.im - c.im);
}
// 字符串描述(重写Object的toString方法,输出a+bi的形式)
public String toString() {
if (im < 0)
return real + "" + im + "i";
else
return real + "+" + im + "i";
}
// 相等比较(判断两个复数是否相等,需要重写Object的equals方法)
public boolean equals(Object obj) {
Complex1 c = (Complex1) obj;
if (real == c.real && im == c.im) {
return true;
}
return false;
}
}
// 定义测试类
public class Example1 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入第一个复数的实部和虚部:");
double a=sc.nextDouble();
double b=sc.nextDouble();
Complex1 c1 = new Complex1(a, b);// 创建Complex对象
System.out.println("请输入第二个复数的实部和虚部:");
double c=sc.nextDouble();
double d=sc.nextDouble();
Complex1 c2 = new Complex1(c, d);// 创建Complex对象
System.out.println("("+c1.toString()+")+("+c2.toString()+")=" + (c1.add(c2)));// 调用add方法并打印
System.out.println("("+c1.toString()+")-("+c2.toString()+")=" + c1.minus(c2));// 调用minus方法并打印
if(c1.equals(c2))//调用toString方法
System.out.println(c1.toString()+"="+c2.toString());
else
System.out.println(c1.toString()+"≠"+c2.toString());
}
}
(2)程序2源代码
import java.util.Scanner;
import java.text.DecimalFormat;
//定义了Area接口
interface Area {
double getArea(); // 定义抽象方法getArea()
}
// 定义了Volume接口
interface Volume {
double getVolume(); // 定义抽象方法getVolume()
}
// 声明球类Globe,实现,计算球的表面积和体积
// Globe类实现了Area和Volume接口
class Globe implements Area, Volume {
double r;
public Globe(double r) {
this.r = r;
}
// 实现getArea()方法
public double getArea() {
return 4 * Math.PI * r * r;
}
// 实现getVolume()方法
public double getVolume() {
return 0.75 * Math.PI * r * r * r;
}
}
// 定义测试类
public class Example4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
DecimalFormat df = new DecimalFormat("0.00");
System.out.println("请输入球的半径:(单位:cm)");
double rad = sc.nextDouble();
Globe globe = new Globe(rad);// 创建Globe类对象实例
System.out.println("此球的表面积为" + df.format(globe.getArea())+"cm²");// 调用Dog类的getArea()方法
System.out.println("此球的体积为" + df.format(globe.getVolume())+"cm³");// 调用Dog类的getVolume()方法
}
}
(3)程序3源代码
import java.util.Scanner;
import java.text.DecimalFormat;
//定义了平面图形PlaneGraphics接口
interface PlaneGraphics {
double area(); // 定义求面积的抽象方法area()
double perimeter(); // 定义求周长的抽象方法perimeter()
}
// 定义了立体图形SolidGraphics接口
interface SolidGraphics {
double volume(); // 定义求体积的抽象方法volume()
}
// 定义长方形Rectangle类实现平面图形PlaneGraphics接口
class Rectangle implements PlaneGraphics {
double a, b;
// 定义了两个参数的构造函数
public Rectangle(double a, double b) {
this.a = a;
this.b = b;
}
// 实现求面积的抽象方法area()
public double area() {
return a * b;
}
// 实现求周长的抽象方法perimeter()
public double perimeter() {
return 2 * (a + b);
}
}
// 定义长方体Cuboid类继承长方形Rectangle类的同时实现立体图形SolidGraphics接口
class Cuboid extends Rectangle implements SolidGraphics {
double c;
// 定义了三个参数的构造函数
public Cuboid(double a, double b, double c) {
super(a, b);
this.c = c;
}
// 实现求表面积的抽象方法area()
public double area() {
return 2 * (a * b + b * c + a * c);
}
// 实现求体积的抽象方法volume()
public double volume() {
return a * b * c;
}
}
// 定义测试类
public class Example6 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
DecimalFormat df = new DecimalFormat("0.00");
System.out.println("请输入长方形的长和宽:(单位:cm)");
double recLength = sc.nextDouble();
double recWidth = sc.nextDouble();
// 创建Rectangle类对象
Rectangle rectangle = new Rectangle(recLength, recWidth);
System.out.println("此长方形的面积为:" + df.format(rectangle.area())+"cm²");
System.out.println("此长方形的周长为:" + df.format(rectangle.perimeter())+"cm");
System.out.println("请输入长方体的长、宽、高:(单位:cm)");
double cubLength = sc.nextDouble();
double cubWidth = sc.nextDouble();
double cubHeight = sc.nextDouble();
// 创建Cuboid类对象
Cuboid cuboid = new Cuboid(cubLength, cubWidth, cubHeight);
System.out.println("此长方体的表面积为:" + df.format(cuboid.area())+"cm²");
System.out.println("此长方体的体积为:" + df.format(cuboid.volume())+"cm³");
}
}
(4)程序4源代码(如选做)
//定义接口Plan
interface Plan {
void eat(); // 定义抽象eat()方法
void play(); // 定义抽象play()方法
}
// 定义Saturday类实现Plan接口
class Saturday implements Plan {
// 实现抽象eat()方法
public void eat() {
System.out.println(" 吃甜品");
}
// 定义抽象play()方法
public void play() {
System.out.println(" 骑自行车");
}
}
// 定义Sunday类实现Plan接口
class Sunday implements Plan {
// 实现抽象eat()方法
public void eat() {
System.out.println(" 吃寿司");
}
// 定义抽象play()方法
public void play() {
System.out.println(" 爬山");
}
}
// 定义测试类
public class Example9 {
public static void main(String[] args) {
weekend(new Saturday());
weekend(new Sunday());
}
// 定义静态的weekend()方法,接收一个Plan类型的参数
public static void weekend(Plan p) {
// 判断所属类型进而使用其特有方法
if (p instanceof Saturday) {
System.out.println("星期六:");
} else {
System.out.println("星期天:");
}
p.eat();
p.play();
}
}