8

考虑这个示例代码,我首先使用普通类来实现泛化概念,然后使用子类来专门化:

package check;
class figure{
  void area(){
  System.out.println("\n Superclass for any figure"); //An useless print statement
  }
}

class triangle extends figure{
  void area()
  {
    System.out.println("\n Code to determine area of a triangle");
  }
}

对于使用抽象类的相同实现,代码将是:

abstract class figure1{
  abstract void area();
}

class triangle1 extends figure1{
  void area()
  {
    System.out.println("\n Code to determine area of a triangle");
  }
}

现在阅读我的 JAVA 教科书(Herbert Schildt,完整参考,第 7 版),在我看来,作者想要传达的是,在泛化-专业化方法的情况下,以某种方式使用抽象类会更好。但是,我不明白它比使用普通课程更好。使用抽象类本质上强制我们扩展基类,仅此而已;除此之外,我看不到实施中有任何巨大差异。那么任何人都可以让我理解使用抽象类是比使用普通类更好的实践/方法吗?

4

7 回答 7

11

抽象类永远不能被实例化,这是抽象类的真正优势。

例如,类Animal可以是抽象类;但在现实生活中,你永远不会有一个Animal;的实例。这根本没有意义,因为您不能只创建一个动物,而是创建一个动物,例如 aCatDog在现实生活中,因为它们是现实世界的实体。因此,在代码设计与现实世界概念或情况之间的转换方面,抽象类要好得多,因为它们可以更简洁地描绘现实世界的情况。

于 2013-11-08T18:03:27.340 回答
8

没有“更好”或“更差”,这取决于你的目的。

如果子类本身不是抽象类,抽象类允许声明需要由子类实现的抽象方法。

非抽象没有,您需要实现所有声明的方法。

将抽象类视为“通用”对象,它在现实生活中不存在,但为许多其他具体对象提供了很好的概括。

把非抽象类想象成你在现实生活中实际上可以指手画脚的东西。

于 2013-11-08T18:03:58.537 回答
7

使用抽象方法意味着没有人可以实例化该类。

换句话说,没有人可以创建一个形状然后使用它:他们必须创建扩展形状的东西,例如圆形或矩形。

于 2013-11-08T18:01:23.447 回答
1

除了其他人指出的之外,拥有抽象类的另一个好处是您可以根据需要向其添加更多子类。假设您有Shape抽象类和CircleTriangle concrete类,将来如果您需要,Polygon您可以轻松添加它。

abstract类作为高级实体,concrete将类作为实体的更多specialized形式,generic具有专门的类继承泛型类的所有属性并定义其与泛型类不同的行为

于 2013-11-08T18:09:30.980 回答
0

您还可以查看 Effective Java 关于该equals()方法的指令。当您在继承关系中有两个具体类时,以尊重合同的方式实现该方法是很棘手的,如果不是完全不可能的话。

于 2013-11-08T18:05:07.797 回答
0

使用抽象类本质上强制我们扩展基类,仅此而已;除此之外,我无法看到实施中的任何巨大差异。那么任何人都可以让我理解使用抽象类是比使用普通类更好的实践/方法吗?

抽象类的用途与接口相同——它创建一个功能契约,说明如果我有它的实例,我知道这些方法将可用。抽象类的另一个好处是它可以包含子类将共享的方法的实现,而无需在子类中实现所述方法。

 public abstract class AbstractFoo{
    public abstract void process(); // subclasses forced to implement
    public String getValue(Object b){
         String s = "Hi!!";
         // stuff happens....maybe
         return s;
 }

 public class ConcreteFoo extends AbstractFoo{
     public void process(){
         // you forced me to!! Oh well, I want to honor the contract
         // anyway
     }
 }

 public class Main{
     public static void main(String[] args){
        AbstractFoo f = new ConcreteFoo();
        System.out.println(f.getValue(new Object()));
     }
 }

这给

 Hi!!

作为输出。通知ConcreteFoo不必执行getValue

于 2013-11-08T18:23:29.483 回答
0

抽象类是被声明为抽象的类——它可能包含也可能不包含抽象方法。抽象类不能被实例化,但它们可以被子类化。Abstract classes最常见的是子类化以共享实现部分。单个抽象类由具有很多共同点的类似类子类化,这为 OOP 设计提供了灵活性。我们使用这个类来抽象出各种类型的类中共有的属性。

例如,假设我们的圆形、矩形、线条图形对象的状态有很多共同点,例如:position, orientation, line color, fill color. 但是,如果我们将一个Abstract类定义为:

abstract class GraphicObject {
    int x, y;
    Color color;

    abstract void draw();

}

现在, 的每个非抽象子类GraphicObject,例如CircleRectangle,都必须提供该draw方法的实现,其中可能包含特定位置的特定颜色的绘制代码(我可能希望用颜色绘制圆形,用不同颜色绘制red矩形green位置(x,y)):

class Circle extends GraphicObject {
    void draw() {
        ...
    }

}
class Rectangle extends GraphicObject {
    void draw() {
        ...
    }

} 

最强大的面向对象技术之一是子类型多态性,它能够从一个单一的supertype观点处理多种特殊类型。

查看这篇文章以深入了解:

  1. 揭示亚型多态性背后的魔力
  2. 使用接口和抽象类最大限度地提高灵活性
于 2013-11-08T18:26:39.257 回答