Java - 将抽象类转换为普通类

时间:2011-02-13 23:03:03

标签: java class abstract

public abstract class Figure
{
  private int offset;

  public Figure()
  {
    offset = 0;
  }

  public Figure(int theOffset)
  {
    offset = theOffset;
  }

  public void setOffset(int newOffset)
  {
    offset = newOffset;
  }

  public int getOffset()
  {
    return offset;
  }

  public abstract void drawHere();

  /**
   * Draws the figure at lineNumber lines down from the
   * current line.
   */

  public void drawAt(int lineNumber)
  {
    int count;
    for(count = 0; count < lineNumber; count++)
      System.out.println();
    drawHere();
  }
}

在这个类中,它处理用于创建树的图形。我试图通过简单地给一个抽象方法的主体把它变成一个普通的类。我注意到当我删除抽象标签时,它仍然完全正常。但我的问题是,如果我想让这个课程不抽象,我会通过什么方式来完成这个?

此类由其他2个类扩展,然后它具有主类。我是否必须经历并修改它们?

7 个答案:

答案 0 :(得分:2)

你不应该改变图;你应该扩展它。

  

此课程由另外2个课程延长   类然后它有主要的   类。我必须经历吗?   修改那些?

更多的理由不改变图:你将打破剩下的代码。

你不应该修改任何东西。创建一个扩展Figure的新类,并使用您想要的行为覆盖抽象drawHere()方法。

答案 1 :(得分:2)

当你有一个抽象类时,

abstract class AbstractCar {

    float maxSpeed;
    Driver whoIsDriving;

    AbstractCar(float ms, Driver d) {
        maxSpeed = ms;
        if(!validateDriver(d)) throw new InvalidDriverException();
        whoIsDriving = d;
    }

    abstract boolean validateDriver(Driver d);

}

您可以通过扩展和定义相关的抽象方法,为各种条件分别定义行为。

class CrappyCar extends AbstractCar {    
    boolean validateDriver(Driver d) {
        return d.hasLicense() && d.hasInsurance();
    }
}

class ExpensiveCar extends AbstractCar {
    boolean validateDriver(Driver d) {
        return d.hasLicense() && d.hasInsurance() && d.hasGoodJobInCaseHeMessesUpMyCar();
    }
}

答案 2 :(得分:0)

如果您需要非抽象类,则不得使用abstract修饰符(即仅public class Figure)声明它。不应该修改任何派生类(只要它们本身不是抽象的)。

答案 3 :(得分:0)

从技术上讲,为了使抽象类非抽象,你必须:

  • 为所有抽象方法提供实施
  • 由于您现在拥有所有定义的有效实现,因此请删除所有抽象标记

没有必要修改继承类中的任何内容(假设它们本身是非抽象的),因为它们已经提供了其父类的所有抽象方法的实现。可以自由地覆盖他们希望的任何方法。

你是否应该让你的课程不抽象是另一个讨论点。

答案 4 :(得分:0)

你是正确的,删除​​abstract关键字并实现抽象方法会使该类非抽象。

但是,您通常不希望将类本身从抽象变为非抽象。在添加此关键字之前,类不是抽象的,因此您(或其他人)显然有理由确保它不是普通类,而是抽象类。

如果你想到它的水平很高(远离Java),那么“树”是你知道如何绘制的。同样,你可以想象一个子类“Circle”,你知道它是什么样的画面。然而,对于非常通用的“图”,你不知道绘制它意味着什么。

这就是为什么实际绘图在abstract课程中留下Figure的原因。因此,您不应该使Figure非抽象,而是通过实现Figure中的所有抽象方法,专注于从中扩展的类并使这些非抽象。在Tree课程中,您知道drawHere应该做什么,因此请在那里实施以打印树。在另一个类中,例如Circle,你以不同的方式实现它,但在Figure中实现它永远不会有意义,在那里你不知道要绘制什么。

答案 5 :(得分:0)

你可以为drawHere()声明一个方法体(可能是空的,因为正如@Frank指出的那样,你真的不知道如何绘制Figure)并删除{ {1}}修饰符。然后你将有一个具体的课程。这意味着有人可以创建abstract。这不是您现在拥有的两个子类中的任何一个,只是new Figure()

如果这样一个对象(当它被调用到Figure时什么都不做)就没用了(特别是,如果你认为这个对象是错误的话),那么你应该保持班级抽象。即使您可以为每个方法定义一个实现,这种推理也适用。

答案 6 :(得分:0)

如果一个类是抽象的,你可以赋予所有方法的主体,或者没有这些方法,但是如果任何类正在扩展抽象类,它必须实现所有仅被声明的方法。