25

我了解为什么我们需要 Java 中的抽象类 - 来创建子类。但是同样可以通过具体的类来实现。例如,Class Child 扩展了 Parent。这里的 Parent 可以非常抽象和具体。那么为什么我们有抽象?

4

7 回答 7

55

抽象类不能直接实例化。将一个类声明为抽象意味着您不希望它被实例化并且该类只能被继承。您正在代码中强加一个规则。

如果您进一步扩展您的父/子关系示例以包含一个 Person 类,那么将 Person 设为抽象是很有意义的。父母是一个具体的想法,孩子也是。人是现实和代码中的抽象概念。

一个好处是您明确定义和保护抽象类的想法。当您将类声明为抽象时,您或使用您的代码的任何其他人都无法通过实例化它来错误地使用它。这种推理类似于为什么我们将函数和字段指定为公共、私有或受保护的。如果您将函数或成员声明为私有,则实际上是在保护它免受来自客户端代码的不当访问。Privates 是用来在类中使用的,仅此而已。抽象类意味着被继承,就是这样。

现在,您是否必须使用抽象类并将函数和字段定义为私有而不是公共?不,你没有。但是提供这些概念是为了帮助保持代码整洁和组织良好。据我所知,抽象类是用所有面向对象的语言实现的。如果你环顾四周,你会发现 C++、C#、VB.NET 等都使用这个概念。

一个更好的,具体的例子:

形状层次UML图

在上面的示例中,Shape 类应该是抽象的,因为它本身没有用。

于 2012-04-18T14:19:56.353 回答
10

抽象类意味着它是抽象的不完整的。它需要另一个类来完成它和/或其功能。您需要扩展抽象类。它将对某些类很有用,例如。水果 所有水果都具有相同的属性,例如颜色。但是你可以对不同的水果有不同的特性,比如它是果肉,比如橙子,还是不是香蕉等。

于 2012-04-18T14:23:50.523 回答
4

我知道这是一个老问题,但看起来发帖者仍然对使用抽象类的好处有一些疑问。

如果你是唯一一个会使用你的代码的人,那么真的没有任何好处。但是,如果您正在编写代码供他人使用,则有好处。例如,假设您编写了一个缓存框架,但希望允许客户端创建自己的缓存实现类。您还希望跟踪一些指标,例如假设打开了多少缓存。您的抽象类可能看起来像这样:

public abstract class AbstractCache {
    public final void open() {
        ... // Do something here to log your metrics
        openImpl();
    }

    protected abstract void openImpl() { }
}

AbstractCache 类本身是无用的,您不希望客户端尝试实例化一个并将其用作缓存,如果该类是具体的,他们将能够做到这一点。您还想确保他们无法绕过您的指标日志记录,如果您只为他们提供缓存接口,他们将能够做到这一点。

于 2013-09-25T19:17:00.833 回答
3

抽象的重点不是创建子类。它更多是关于在您的代码中创建接缝。您希望代码可测试和解耦,从而实现可维护性的最终目标。出于类似的原因,抽象也使我们能够在不产生副作用的情况下替换一些代码。

于 2012-04-18T14:25:54.760 回答
3

抽象类旨在用作派生其他类的基类。派生类应为未在基类中实现的方法提供实现。实现所有缺失功能的派生类称为具体类

于 2016-07-22T05:38:42.530 回答
0

根据我的理解

抽象类是一个只描述行为但不实现它的类。考虑抽象类的这个 Java 示例:

public interface DoSomething(){
public void turnOnTheLight(); 
}

具体类是那些要实现的类。例如:

    public abstract class A(){
        public void doIt(); 
    } 
    public class B extends A(){
        public void doIt(){ 
        //concrete method
        System.out.println(“I am a Concrete Class Test”); 
    }
 }

换句话说,java中的具体类是任何这样的类,它具有从接口或抽象类继承的所有成员的实现。

于 2017-06-01T14:18:28.730 回答
0

对于那些只寻求纯技术方法差异的人来说,具体父类和抽象父类之间最明显的区别是子类有义务包含/实现特定方法。

具体的父类不能强制/强制其子类包含/实现方法。抽象父类通过声明抽象方法来强制其子类这样做。

除了上述之外,还涉及到设计和功能要求来决定抽象类的使用。这样的例子可以在javax.servlet.http.HttpServlet课堂上找到

于 2020-04-30T21:47:38.223 回答