package cn.edu.seig.zhangxiaohu;
//抽象类多态的应用示例

public abstract class Shape {							//Shape为抽象类
	public abstract String getTypeInfo();		//抽象方法,获取Shape的类型信息
	public abstract String getAreaInfo();		//抽象方法,获取面积信息
	public abstract String getPerimeterInfo();	//抽象方法,获取周长信息
}

package cn.edu.seig.zhangxiaohu;
public interface AuthorInfo  {	//接口,提供创建者信息
String getAuthorInfo();
}

package cn.edu.seig.zhangxiaohu;
public class Circle extends Shape implements AuthorInfo  {
//Circle类继承了Shape抽象类,实现AuthorInfo  接口
	private int radius;	//定义一个int类型的私有成员变量,命名为radius,表示圆半径
	public Circle(int r){
		radius = r;   //利用形式参数 r初始化成员变量radius
	}
	//实现抽象方法 getTypeInfo()
	public String getTypeInfo(){
		return "类型:圆,半径:" + radius;
	}
//实现获取面积的抽象方法
	public String getAreaInfo() {
		return "面积:" + Math.PI * radius * radius;
	}
	//实现获取周长抽象方法
	public String getPerimeterInfo() {
		return "周长:" + 2 * Math.PI * radius;
	}	
	public String getAuthorInfo(){
		return "作者:张小虎"; //替换为自己的姓名,否则影响得分
	}
}

package cn.edu.seig.zhangxiaohu;
class Rect extends Shape implements AuthorInfo {	
//子类Rect类继承了Shape抽象类,实现AuthorInfo  接口
	private int length;	//定义一个int类型的私有成员变量,命名为length,表示矩形的长
	private int width;	//定义一个int类型的私有成员变量,命名为width,,表示矩形的宽

	public Rect(int l, int w){
		length = l;   //利用形式参数 l、w分别初始化长、宽成员变量
		width = w;
	}
	//实现抽象方法 getTypeInfo()
	public String getTypeInfo(){
		return "类型:矩形," + length + "x" + width;
	}
	public String getPerimeterInfo(){
		return "周长:" + 2 * (length + width);
	}
	public String getAreaInfo(){
		return "面积:" + length * width;
	}
	public String getAuthorInfo(){
		return "作者:张小虎"; //替换为自己的姓名,否则影响得分
	}
}

// 主类
public class MyApp {
	public static void main(String[] args) {
		Shape shapes[] = new Shape[6];
		Circle c1 = new Circle(50);  //实例化半径为10的圆
		Shape c2 = new Circle(100);  //实例化半径为20的圆
		AuthorInfo c3 = new Circle(200);  //实例化半径为30的圆

		Shape r1 = new Rect(100,100);
		Rect r2 = new Rect(180,160);
		AuthorInfo r3 = new Rect(200,240); 

		int pos = 0;
		shapes[pos++] = c1;
		shapes[pos++] = r1;
		shapes[pos++] = r2;
		shapes[pos++] = c2;
		shapes[pos++] = (Shape) c3;  //(17)_______________为什么此处和下一行需要强制类型转换
		shapes[pos++] = (Shape) r3;  

		pos = 1;
		for (Shape s : shapes ) {
			System.out.print("第" + pos + "个形状:" + s.getTypeInfo() + ",");	
			System.out.print(((AuthorInfo) s).getAuthorInfo() + ",");	
			System.out.print(s.getPerimeterInfo() + ",");	
			System.out.print(s.getAreaInfo());
			System.out.println();	
			pos++;
		}
	}
}

解释:

  1. 为什么需要强制类型转换?

    • 数组 shapes 的类型是 Shape[],只能存放 Shape 类型的对象或其子类。
    • c3r3 的类型分别是 AuthorInfo,而 AuthorInfo 是一个接口,接口本身不能实例化,所以 c3r3 实际上分别指向一个 Circle 对象和一个 Rect 对象。
    • 由于 CircleRect 都是 Shape 的子类,所以需要进行强制类型转换,将 c3r3 转换成 Shape 类型,才能存放到 shapes 数组中。
  2. 代码说明:

    • 抽象类 Shape 定义了三个抽象方法 getTypeInfo()getAreaInfo()getPerimeterInfo(),用于获取形状的类型信息、面积信息和周长信息。
    • 接口 AuthorInfo 定义了一个抽象方法 getAuthorInfo(),用于获取创建者信息。
    • 子类 CircleRect 分别继承了 Shape 抽象类并实现了 AuthorInfo 接口。它们分别实现了父类和接口的抽象方法,并添加了各自的成员变量和构造函数。
    • 主类 MyApp 中,创建了 shapes 数组,并实例化了多个 CircleRect 对象。
    • 由于 shapes 数组只能存放 Shape 类型对象,所以需要将 c3r3 强制转换成 Shape 类型后才能存入数组。
    • 最后,使用循环遍历 shapes 数组,调用每个对象的方法,输出每个形状的类型信息、创建者信息、周长信息和面积信息。

运行结果截屏(result.png):

result.png

Java 抽象类和接口:Shape 和 AuthorInfo

原文地址: https://www.cveoy.top/t/topic/nhBZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录