抽象类,抽象方法,继承调用实现
题目
请根据UML图和下列要求编写程序:
(1)定义一个名为Shape的抽象类,该类有一个抽象方法getArea()。
(2)定义一个名为Circle的圆形子类,该类的数据成员有半径(radius),实现父类方法getArea()用于计算圆形的面积。equals()方法重写父类Object的equals() 方法,用于比较两个圆形对象是否相等,如果两个圆形半径一样,那就是相等,否则不等。
(3)定义一个名为Cylinder的圆柱体子类,该类包含一个高度(height)的数据成员和一个重写父类方法的getArea()方法,用于计算圆柱体的表面积。
(4)UML图中未说明的内容,根据自己的理解自行编程实现。
(5)编写一个测试程序,创建一个Shape类型的数组,数组有两个元素,分别是一个Circle对象(半径2.3)和一个Cylinder对象(半径3.6,高度5.8),通过循环语句遍历数组每个元素并输出数组元素的面积,该循环语句要能体现面向对象的多态特性。
UML类图
代码
package zuoye;
public class zuoye11_2 {
public static void main(String[] args){
Shape[] shape={new Circle(2.3),new Cylinder(3.6,5.8)};
for(Shape temp:shape){
System.out.println(temp);
System.out.println(temp+" Area : "+temp.getArea());
}
}
}
abstract class Shape{
protected abstract double getArea();
}
class Circle extends Shape{
private double radius;
public Circle(){
}
public Circle(double radius){
this.radius=radius;
}
public double getRadius(){
return this.radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
protected double getArea(){
return Math.PI*radius*radius;
}
@Override
public boolean equals(Object o) {
if (o instanceof Circle) {
return (this.radius == ((Circle) o).radius);
} else {
return false;
}
}
}
class Cylinder extends Circle{
private double height;
public Cylinder(){
}
public Cylinder(double radius,double height){
super.setRadius(radius);
this.height=height;
}
public double getHeight(){
return height;
}
public void setHeight(double height){
this.height=height;
}
@Override
protected double getArea(){
return super.getArea()*2+super.getRadius()*2*height*Math.PI;
}
@Override
public boolean equals(Object o){
if(o instanceof Cylinder){
return this.getRadius()==((Cylinder) o).getRadius()&&this.height==((Cylinder) o).getHeight();
}
else {
return false;
}
}
}
输出
Cylinder的equals方法第二种写法
@Override
public boolean equals(Object o) {
if(o instanceof Cylinder) {
//两个圆柱对象相等的条件假设是:底面圆半径相等且高度相等
Cylinder cylinder=(Cylinder)o;
return super.getRadius() == ((Circle)cylinder).getRadius() && this.height == cylinder.height;
}else {
return false;
}//这里面的(Circle)cylinder).getRadius() ,(circle)可以省略,因为没用
}
抽象类的特点
-
抽象类不能直接实例化,并且对抽象类使用 new 运算符会导致编译时错误。虽然一些变量和值在编译时的类型可以是抽象的,但是这样的变量和值必须或者为 null,或者含有对非抽象类的实例的引用(此非抽象类是从抽象类派生的)。
-
允许(但不要求)抽象类包含抽象成员。
-
抽象类不能被密封。
-
abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
-
在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
-
abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
-
实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
-
接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
-
抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
-
接口中的方法默认都是 public,abstract 类型的。