RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1133215
Accepted
Александр
Александр
Asked:2020-05-29 18:50:50 +0000 UTC2020-05-29 18:50:50 +0000 UTC 2020-05-29 18:50:50 +0000 UTC

Java中使用抽象类与接口的区别与正确性

  • 772

我试图了解这两个元素有何不同。我在这里和这里阅读,以及我正在学习的讲座。如果我理解正确,除了定义和连接之外,我还看到以下可能性:

抽象类

  1. 不能实例化一个类
  2. 至少必须定义方法的标头,因此继承者必须覆盖此方法
  3. 方法可以完全实现
  4. 该方法可以被继承人覆盖,因此将获得1个方法
  5. 不固定的变量值

界面

  1. 接口无法实例化
  2. 必须定义方法头
  3. 该方法可以被覆盖,结果将有2个方法(尽管如果一个就足够了,为什么我们需要这么多方法)
  4. 方法可以使用默认值定义
  5. 变量的固定值

我知道接口定义状态,而抽象类定义状态和行为。那么为什么不只使用一个变体,例如一个类呢?

我们只能从一个类继承,但可以从多个接口继承。但是,为什么不创建更多的抽象类并相互继承,从而在工作类中继承一些东西呢?

什么时候应该使用一个而不是另一个?

是否存在需要使用一个或另一个选项的用例?

对Java中的应用程序感兴趣。

加法 假设有这样的结构。

abstract class Figure {
    double dim1;
    double dim2;

    Figure(double a, double b) {
        dim1 = a;
        dim2 = b;
    }

    abstract double area();
}

有一个三角形类:

class Rectangle extends Figure {
    Rectangle(double a, double b) {
        super(a, b);
    }

    double area() {
        System.out.println("B области четырехугольника.");
        return dim1 * dim2;
    }
}

有一个正方形类:

class Triangle extends Figure {
    Triangle(double a, double b) {
        super(a, b);
    }

    double area() {
        System.out.println("B области треугольника.");
        return dim1 * dim2 / 2;
    }
}

有一个入口点:

class AbsractAreas {
    public static void main(String[] args) {
        Rectangle r = new Rectangle(9, 5);
        Triangle t = new Triangle(10, 8);
        Figure figRef = r;
        System.out.println("Площадь равна " + figRef.area());
        figRef = t;
        System.out.println("Площадь равна " + figRef.area());
    }
}

我可以将其转换为接口吗?应该转换成接口吗?还是应该一分为二?

PS:接口的附加问题。我知道接口旨在保护类的工作方式。但是对类施加限制还不够吗(我的意思是访问修饰符)?

PS PS:为什么要在接口中添加定义方法体的功能?而现在,如果我在接口中定义一个方法,例如move (int n),在继承人中,我需要使用move (int n, int m). 用一个方法创建一个抽象类move ()然后重新定义它以获得所需数量的参数不是更容易吗?或者您是否有能力在接口中覆盖方法中的参数数量?还是我们仍然有两种方法move (int n)和move (int n, int m)?

PS PS PS:抱歉这么多问题。我只是想深入了解这个问题。)

java
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    WiMank
    2020-05-29T19:15:32Z2020-05-29T19:15:32Z

    接口定义了行为,一般意义上,接口告诉了如何与这个接口实现的类一起工作,例如所有的门都可以关闭和打开,不管它是什么门,它是怎样的制造,主要是它是一扇门,它有打开和关闭的方法。接口可以被在任何意义上彼此不相关的类使用(以 Comparable 为例)。最重要的是多重继承。

    抽象类定义行为和状态。抽象类用于继承(即我们之间有密切关系的类),用它来描述继承人的共同特征。它可以包含特定的(在接口中也使用 java 8)和静态方法。

    PS我发现一篇文章很可能会帮助您更好地理解差异链接

    • 3
  2. Roman-Stop RU aggression in UA
    2020-05-29T20:26:39Z2020-05-29T20:26:39Z

    考虑一个需要接口并且不能省略抽象类的示例。

    这是我们需要在一个类中组合多个功能方面的情况,而这些方面之间没有任何关系(因此制作抽象类并相互继承是不切实际的,甚至是不可能的)。

    让我用一个例子来解释。假设我们需要机会

    1. 创建对象的副本。
    2. 比较对象
    3. 将对象序列化为字节数组

    为此,您可以创建如下接口:

    interface Clonable<T> {
      T clone();
    }
    interface Comparable<T> {
      int compare(T other);
    }
    interface Serializable {
      byte[] asBytes();
    }
    

    或者 - 创建具有相同方法的抽象类。

    您需要了解这些类或接口并不是凭空存在的。我们假设这些接口(或类)具有使用它们的客户端,例如库。例如,Serilizable- 用于通过网络进行消息传递的库的Comparable一部分,以及 - 用于处理馆藏的库的一部分。

    那些。某处有使用它们的功能:

      void sort(List<Comparable> list);
    

    现在,当我们想要创建一个应该能够复制自身的具体类,以便它可以进行比较和序列化时,使用接口一切都很简单——我们创建一个类并实现所有三个接口。

    如果我们使用抽象类,就会出现问题:

    1. 拥有所有三种可能性,哪个类应该从谁那里继承?
    2. 如果我们在完全不相关的不同库中拥有所有三个抽象类(由彼此不了解的不同开发人员制作,并且根本不知道有人可能需要使用另一个库中的类)怎么办?
    3. 即使我们选择了某种方式将抽象类组织成层次结构,我们只需要部分功能,不需要层次结构根部的类提供的功能,我们该怎么办?

    总之,抽象类不适合这项任务。主要原因是java中缺少多重继承。多重继承可以解决这个问题,但代价是引入了新问题(多重继承本身固有的)。

    接口(特别是从 java8 开始)可以取代抽象类(与其他措施一起)。但有时使用抽象类可能更实用。

    假设我们正在创建一个用于在数据库中保存对象的库。您可以为可以持久化的对象创建一个接口:

    interfact Persistable<K> {
      K getId();
    }
    

    但是,在这种情况下,实现的每个具体类Persistable都必须定义一个字段id。如果有很多这样的类,那么把它变成Persistable一个抽象类然后它可以存储状态可能更实用:

    abstract class Persistable<K> {
      private K id;
    
      public K getKey() {
        return id;
      }
    

    这当然是一个简单的例子,在这里是不合理的,但是如果有更多这样的字段,加上这些字段必须满足某些条件,才能Persistable正确构造对象(例如,什么id != null),那么可以让继承类对此感到不舒服,因为 相同的逻辑将在多个地方,并且在支持方面将其放在一个地方更方便。

    这可以帮助检测后继者中的错误,其中后继者(非恶意)在早期阶段错误地实现了接口。

    当然,实现实现继承和使用抽象类也有缺点,在特定情况下需要考虑和权衡。

    • 3
  3. Alexander Chernin
    2020-05-29T19:40:34Z2020-05-29T19:40:34Z

    在大多数情况下,接口是常见行为的标志。例如,如果您的对象可以被克隆,那么在其类的祖先中可能有一个 interface Cloneable。如果对象是可移动的,那么 -Moveable等等。并且标志的方法是适当的——它们的目的是指定这个!,而不是实现标志接口继承者的类对象的行为。

    抽象类仍然是一个类,或“下类”。也就是说,实体与具体类相同,但缺少一些东西。

    例如,一个抽象类Shape (Форма)是一个实体/类,但是我们不能说这个形状到底是什么(立方体,正方形,圆形,平行六面体),例如,我们不能说如何绘制它,或者抓取它,或者改变如何它有很多顶点和边,所以这个实体很可能有某种部分实现,例如,改变和存储窗体中心在空间或平面上的位置的方法,但我们将离开显示和这种实体对后代/继承人的特定行为。

    如果有架构/语义需要,这两种结构本身可以继承相同的接口和抽象类。

    Z.Y. 了解差异的最佳方法是实践!在开发应用架构和后续实现的过程中,相同的实体之一可以先成为接口,然后是类(甚至是抽象类),反之亦然)

    • 2

相关问题

  • wpcap 找不到指定的模块

  • 如何以编程方式从桌面应用程序打开 HTML 页面?

  • Android Studio 中的 R.java 文件在哪里?

  • HashMap 初始化

  • 如何使用 lambda 表达式通过增加与原点的距离来对点进行排序?

  • 最大化窗口时如何调整元素大小?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5