Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 抽象方法和类:背后的概念?_Java_Inheritance_Subclass_Abstract_Superclass - Fatal编程技术网

Java 抽象方法和类:背后的概念?

Java 抽象方法和类:背后的概念?,java,inheritance,subclass,abstract,superclass,Java,Inheritance,Subclass,Abstract,Superclass,拥有一个抽象类(在我的例子中,我指的是java)背后的整个概念到底是什么。 我理解这样一个事实,即它太笼统,无法自行实现,因此没有用处。但是可以肯定的是,只要声明它为非抽象类并使用与抽象类相同的继承,就会得到相同的结果 节省时间的主要优点是在没有方法体的抽象超类中声明抽象方法,然后在其子类中重写它们吗 假设您的基类有一个必须在任何有用的子类中重写的方法。如果在基类中实现该方法,并且该方法未被重写,则在运行伪方法体之前不会发现错误。如果将方法和类抽象化,编译时会发现错误。当您不想创建一个类的对象时

拥有一个抽象类(在我的例子中,我指的是java)背后的整个概念到底是什么。 我理解这样一个事实,即它太笼统,无法自行实现,因此没有用处。但是可以肯定的是,只要声明它为非抽象类并使用与抽象类相同的继承,就会得到相同的结果


节省时间的主要优点是在没有方法体的抽象超类中声明抽象方法,然后在其子类中重写它们吗

假设您的基类有一个必须在任何有用的子类中重写的方法。如果在基类中实现该方法,并且该方法未被重写,则在运行伪方法体之前不会发现错误。如果将方法和类抽象化,编译时会发现错误。

当您不想创建一个类的对象时,将该类抽象,子类的常用方法可以在抽象的超类中实现,另一个目的是将该方法抽象,以便子类必须实现超类抽象方法来编写自己的方法实施就这么简单。

主要优点是您不能实例化抽象类。您可能有一个类
文档
,如下所示:

public class Document {
    public void write(File file) {
        // I have no idea how to implement this
    }
    public void read(File file) {
        // I don't know here either
    }
}
Document doc = new MyDocument();
您希望人们为其文档类型创建子类:

public class MyDocument extends Document {
    public void write(File file) {
        // Now I know how to implement
    }
    public void read(File file) {
        // this also can be implemented
    }
}
但您不希望人们制作新的
文档
s:

Document doc = new Document(); // this should not be allowed
你希望人们做这样的事情:

public class Document {
    public void write(File file) {
        // I have no idea how to implement this
    }
    public void read(File file) {
        // I don't know here either
    }
}
Document doc = new MyDocument();
解决方案是将
文档
抽象化:

public abstract class Document
为了使这些方法更加抽象:

public abstract void write(File file);
public abstract void read(File file);

然后您不能实例化
文档
,但可以实例化子类。子类必须重写
read
write

将抽象类视为在API中创建契约的一种方式

假设您正在创建一个程序,其中包含商店销售的商品列表。现在这个列表当然会包含一些项目,它们有一些共同的特征和一些单独的特征。然而,我们不能出售“物品”-我们想出售“电视”或“桌子”

因此,您将创建一个抽象类“Item”,该类具有价格标签、制造日期等。但是,您永远不希望任何人创建类Item的实例,因为Item可以是任何东西

您希望程序员对Item类型的类进行子类化并创建他们自己的类,以满足Item所需的契约。反过来,API允许您添加子类item的类,将其放在可用项的存储列表中。这还将自动为这些类提供子类化时不需要考虑的功能,并要求您重写必须为该类实现的方法

在Java中,方法不需要在抽象类中是抽象的,并且可以像在普通类中一样实现。例如,如果你有一个orice标签,你可以为这个价格标签实现一个getter——不需要强迫子类实现它


希望它有意义。其他人请随意评论,我可以详细说明。

是的,这有点像安全机制?抽象类中的所有方法是否都需要抽象,即命名为抽象?不只是那些你想要抽象的方法,一旦你有了一个抽象方法,你就需要将类声明为抽象。我建议阅读关于抽象类和方法的文章。我认为这也增加了可读性。将一个方法声明为抽象而不提供方法体比提供一个带有注释的伪方法更清楚地表达了非实现性。这里解释了您的大部分问题:我想我开始得到它了,谢谢,基本上是为了控制,比如尝试和控制实现了什么方法等等,以及不浪费时间为一个超类编写方法,而这个超类是如此的通用以至于它通常没有用处。我还可以问一下,OOP中的大多数超类通常是抽象的吗?这似乎是最明智的做法,因为大多数能够拥有许多子类的事物通常都是非常一般的?抽象,从其定义来看,是关于一般性的。如果我告诉你我有一只动物宠物,你只会知道我有一只宠物,但不知道是哪只。如果我说我有一只狗,那么我们就更具体了,但你只能想象我有什么样的宠物。如果我告诉你我养了一只柯基犬,你会突然知道我养了什么宠物。Java Animal可能被声明为接口,dog可能是一个抽象类,而Corgi是一个普通类。为什么这很有趣?嗯,我的公寓可能不允许养动物宠物,因此排除了任何种类的动物,或者它可能允许猫而不是狗,使用某些类型的动物,但不使用其他类型的动物。抽象类型和概括性用于指定规则和契约。至于界面与抽象部分:我们可以说动物通常需要进食和繁殖。它们是如何做到这一点的,这与我们所谈论的动物非常具体,因此无法说明如何做到(例如,Java中的这些方法,根据它们的定义,是无法实现的)。然而,我们可以为狗实施这些,因为它们的食物和繁殖方式在所有狗种中或多或少是相同的。