抽象类有什么意义?

Lew*_*rin 12 java

我理解OOP范例中的抽象类是什么.是的抽象类是不完整的类型,无法实例化.

抽象类的子类可以扩展超类等,并通过使用基类型变量调用方法.但这是我没有得到的.

我正在读这本书,作者说使用Superclass变量来引用子类并调用一个公共方法调用正确的方法.是的,这是真的.例如我写的这个小代码:

public class ObjectOne extends SuperObject {

    public String objectString()
    {
        return "objectString() of class ObjectOne\n" ;
    }
}



public class ObjectTwo extends SuperObject {

    public String objectString()
    {
        return "objectString() of class ObjectTwo\n" ;
    }
}


public class ObjectThree extends SuperObject {

    public String objectString()
    {
        return "objectString() of class ObjectThree\n" ;
    }
}


public class SuperObject {
    public String objectString()
    {
        return "SuperObject" ;      
    }
}

    import static java.lang.System.out ;
public class ControlClass {

    public static void main(String[] args)
    {
        SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;

        for(SuperObject elem:arr)
        {
            out.println(elem.objectString()) ;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,当main执行正确的方法时,仅使用引用类型为对象调用.我的问题是抽象类的重点是什么?无论方法或类是抽象的,多态性都可以工作.与C++不同,多态性仅您指定时才起作用.对于Java来说,它显然一直很有效.

所以我猜抽象关键字或抽象概念只是为了完成继承层次结构,使不完整的类型无法实例化,或者是为了促进良好的OOP实践?有人可以澄清谢谢.

Jon*_*Jon 11

我不确定你理解抽象类是什么,因为你的例子中没有一个类是抽象的,也没有任何接口.你正在做的是扩展一个可实例化的类.没有abstract关键字,没有什么可以阻止我这样做:

SuperObject obj = new SuperObject();

我认为更好的例子是说明如何使用抽象类.他们通常习惯做的是提供一种通用的方法实现.如果许多类实现了一些接口,但是它们都使用相同的代码以相同的方式实现相同的方法,那么通常做的是创建一个abstract包含公共实现的类,并获得所有具体的实现扩展该课程.这有助于代码重用,并降低了一个开发人员改变一个类的通用方法实现的可能性,但忘记了其他类.例如..

public class ObjectOne extends Thing {
  public String objectString()
  {
      return "objectString() of class ObjectOne\n" ;
  }
}

public class ObjectTwo extends Thing {
  public String objectString()
  {
    return "objectString() of class ObjectTwo\n" ;
  }
}

public class ObjectThree extends Thing {
  public String objectString()
  {
    return "objectString() of class ObjectThree\n" ;
  }
}

public abstract class Thing implements SuperObject {
  public String alwaysTheSame() {
    return "The same thing";
  }
}

public interface SuperObject {
  public String objectString();

  public String alwaysTheSame();
}

import static java.lang.System.out ;

public class ControlClass {

  public static void main(String[] args)
  {
    SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;

    for(SuperObject elem : arr)
    {
        out.println(elem.alwaysTheSame());
        out.println(elem.objectString()) ;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我们在这里做的是介绍一个abstractThing,它提供了一个方法实现,它对所有3个实现SuperObject(现在是一个接口)都是通用的.这意味着我们不必在三个不同的地方再次编写相同的代码,以便SuperObject在每个具体类中完全实现接口.

除此之外,您还可以使用extendfinal课程.您可能希望这样做是为了覆盖具体类中的一个或多个方法的默认行为,或者使用其他方法来修饰该类.当然,当你从头开始设计类层次结构时,你不会在其中粘贴具体的类,然后由其他类扩展,因为它通常被认为是一个糟糕的代码味道.但是,我们很少有人使用全新的写入式代码库,并且必须使现有的代码库适应新的需求.扩展具体类是工具箱中的一个工具来执行此操作.

编辑:误解了OP的要求,但上面的最后一段是相关的.

  • 事实上,你的解释非常好.我喜欢.尼斯 (3认同)

Nic*_*zol 7

假设您想在IpadAndroidIphone桌面应用程序上部署一个应用程序。你在一个重要的部分工作,它将在一个抽象类中完成95% 的工作。然后创建 4 个其他小类,它们将为每个设备以不同的方式实现抽象方法。

这样,您就不会重复 95% 的工作,并且每个设备都会实例化自己的类,该类扩展了抽象公共类。


Sak*_*ket 5

抽象类是创建计划继承层次结构的绝佳方法。对于类层次结构中的非叶类来说,它们也是一个不错的选择。

这是一个很好的详细解释:(摘自此处

选择接口和抽象类不是一个非此即彼的命题。如果您需要更改设计,请将其设为界面。但是,您可能有提供某些默认行为的抽象类。抽象类是应用程序框架内的优秀候选者。

抽象类让你定义一些行为;它们迫使你的子类提供其他子类。例如,如果您有一个应用程序框架,则抽象类可能会提供默认服务,例如事件和消息处理。这些服务允许您的应用程序插入到您的应用程序框架中。但是,有一些特定于应用程序的功能只有您的应用程序才能执行。此类功能可能包括启动和关闭任务,这些任务通常依赖于应用程序。因此,抽象基类可以声明抽象关闭和启动方法,而不是尝试定义该行为本身。基类知道它需要这些方法,但是抽象类让您的类承认它不知道如何执行这些操作;它只知道它必须发起行动。当需要启动时,抽象类可以调用启动方法。当基类调用此方法时,Java 会调用子类定义的方法。