为什么摘要 class 是 "considered incomplete"?
Why an abstract class is "considered incomplete"?
我们知道抽象 class 是一个不完整的 class(它的所有方法都未实现 - # 抽象方法),但是抽象 class 也被称为“一个 class 是 被认为是不完整的 ”。那么,CONSIDERED INCOMPLETE 的正确含义(定义)是什么 class 可以同时具有已实现和未实现的方法?还是其他上下文?
请告知,非常感谢!
正如您所提到的,抽象 class 可以只有方法 signature/contract 说明方法名称是什么,它采用什么参数(如果有的话)以及它具有什么 return 类型(或无效)如果它没有 return 任何东西 - 但没有实际实施它。让我们想象一下,您创建了一个 class 的对象(顺便说一下,您不能)但是如果您只是为了讨论,然后调用其中一个未提供实现的抽象方法,那会怎样你认为应该发生吗?基本上,您正在尝试调用根本没有实现的东西,这将是无效的。因此,由于有可能在您的摘要 class 中未实现一种或多种方法,我们认为摘要 class 更像是一种合同,而不是完全 implemented/complete class.
抽象class用于从真实实例.
中抽象出简单的逻辑
逻辑总是相对于真实的事件或实例而言是相对不完整的。比如猫和虎都会吼,只是声音不同而已。所以,我们可以抽象出roar()
这个方法,这就是逻辑。然后通过使用不同的语音来实现该方法,例如 miao~~miao~~
和 aowu~~aowu~~
这是真实的实例。
可以看到,逻辑简单精炼,但不完整,实例完整但冗余。
问题: class 是否可以同时拥有已实现和未实现的方法?还是其他上下文?
回答:
您不必实现抽象的所有方法 class 但您必须实现它的所有抽象方法。
事实上,扩展抽象 class 与扩展普通 class 没有区别。这不像实现接口。由于您正在扩展,因此您正在创建子class,因此您可以根据需要添加任意数量的方法和属性。
规范说“摘要 class 是不完整的 class,或者 被视为 不完整”,因为您可以有一个摘要 class 已完全实现(参见 java.awt.event.MouseAdapter
作为示例)。 技术上,它是完整的,但并不意味着要这样使用。
如今,人们可能会通过具有默认方法的接口来实现这些抽象适配器 classes(如果对于特定情况,接口完全适合该目的……)。
适配器 classes 背后的想法是提供特定接口的基本实现,该接口仅允许那些对当前用例感兴趣的方法。
java.awt.event.MouseAdapter
实现的接口java.awt.event.MouseMotionListener
和java.awt.event.MouseWheelListener
不太适合说明这种方法的好处,因为它们确实只有两个或一个方法。此外,MouseAdapter
class 也实现了 java.awt.event.MouseListener
但没有实现该接口的任何方法...
所以让我们仔细看看 class java.awt.event.KeyAdapter
that implements the interface java.awt.event.KeyListener
. According to the description for java.awt.event.KeyEvent
,KeyListener
的实现将为您键入的每个字符接收三个事件(有关确切的详细信息,请参阅KeyEvent
的描述):
- KEY_PRESSED – 由
keyPressed()
处理
- KEY_TYPED – 由
keyTyped()
处理,但前提是可以生成有效的 Unicode 字符
- KEY_RELEASED – 由
keyReleased()
处理
如果您的程序只想响应文本输入,它只对 KEY_TYPED 事件感兴趣,并且 KeyListener.keyPressed()
和 KeyListener.keyReleased()
的实现可以保持为空(尽管它们有尽管如此,还是要实施!)。
如果您的程序是某种游戏的实现,您可能对按下的键更感兴趣;在这种情况下,KeyListener.typed()
可能仍为空。
接下来,这些监听器接口经常被用作匿名classes,像这样:
…
KeyListener listener = new KeyAdapter()
{
@Overwrite
void keyTyped( KeyEvent event )
{
// Do something with the event …
}
}
…
如果不使用适配器 class,相同的代码将如下所示:
…
KeyListener listener = new KeyListener()
{
@Overwrite
void keyReleased( KeyEvent event ) { /* Does nothing */ }
@Overwrite
void keyPressed( KeyEvent event ) { /* Does nothing */ }
@Overwrite
void keyTyped( KeyEvent event )
{
// Do something with the event …
}
}
…
额外的行对可读性没有帮助,不是真的。
如前所述,如果接口中的方法将提供一个空的默认实现,则第二个版本 (new
Interface()
{…}
) 看起来像第一个。
这些适配器 class 只是不包含任何抽象方法的抽象 class 的一种可能用例。但我承认,它们中的大多数在接口中使用默认方法会更好——因为这些默认方法当然进入了 Java!适配器 classes 自 Java 1.1 以来就存在,我认为......就像语言规范中的那些短语!
我们知道抽象 class 是一个不完整的 class(它的所有方法都未实现 - # 抽象方法),但是抽象 class 也被称为“一个 class 是 被认为是不完整的 ”。那么,CONSIDERED INCOMPLETE 的正确含义(定义)是什么 class 可以同时具有已实现和未实现的方法?还是其他上下文?
请告知,非常感谢!
正如您所提到的,抽象 class 可以只有方法 signature/contract 说明方法名称是什么,它采用什么参数(如果有的话)以及它具有什么 return 类型(或无效)如果它没有 return 任何东西 - 但没有实际实施它。让我们想象一下,您创建了一个 class 的对象(顺便说一下,您不能)但是如果您只是为了讨论,然后调用其中一个未提供实现的抽象方法,那会怎样你认为应该发生吗?基本上,您正在尝试调用根本没有实现的东西,这将是无效的。因此,由于有可能在您的摘要 class 中未实现一种或多种方法,我们认为摘要 class 更像是一种合同,而不是完全 implemented/complete class.
抽象class用于从真实实例.
中抽象出简单的逻辑逻辑总是相对于真实的事件或实例而言是相对不完整的。比如猫和虎都会吼,只是声音不同而已。所以,我们可以抽象出roar()
这个方法,这就是逻辑。然后通过使用不同的语音来实现该方法,例如 miao~~miao~~
和 aowu~~aowu~~
这是真实的实例。
可以看到,逻辑简单精炼,但不完整,实例完整但冗余。
问题: class 是否可以同时拥有已实现和未实现的方法?还是其他上下文?
回答:
您不必实现抽象的所有方法 class 但您必须实现它的所有抽象方法。
事实上,扩展抽象 class 与扩展普通 class 没有区别。这不像实现接口。由于您正在扩展,因此您正在创建子class,因此您可以根据需要添加任意数量的方法和属性。
规范说“摘要 class 是不完整的 class,或者 被视为 不完整”,因为您可以有一个摘要 class 已完全实现(参见 java.awt.event.MouseAdapter
作为示例)。 技术上,它是完整的,但并不意味着要这样使用。
如今,人们可能会通过具有默认方法的接口来实现这些抽象适配器 classes(如果对于特定情况,接口完全适合该目的……)。
适配器 classes 背后的想法是提供特定接口的基本实现,该接口仅允许那些对当前用例感兴趣的方法。
java.awt.event.MouseAdapter
实现的接口java.awt.event.MouseMotionListener
和java.awt.event.MouseWheelListener
不太适合说明这种方法的好处,因为它们确实只有两个或一个方法。此外,MouseAdapter
class 也实现了 java.awt.event.MouseListener
但没有实现该接口的任何方法...
所以让我们仔细看看 class java.awt.event.KeyAdapter
that implements the interface java.awt.event.KeyListener
. According to the description for java.awt.event.KeyEvent
,KeyListener
的实现将为您键入的每个字符接收三个事件(有关确切的详细信息,请参阅KeyEvent
的描述):
- KEY_PRESSED – 由
keyPressed()
处理
- KEY_TYPED – 由
keyTyped()
处理,但前提是可以生成有效的 Unicode 字符 - KEY_RELEASED – 由
keyReleased()
处理
如果您的程序只想响应文本输入,它只对 KEY_TYPED 事件感兴趣,并且 KeyListener.keyPressed()
和 KeyListener.keyReleased()
的实现可以保持为空(尽管它们有尽管如此,还是要实施!)。
如果您的程序是某种游戏的实现,您可能对按下的键更感兴趣;在这种情况下,KeyListener.typed()
可能仍为空。
接下来,这些监听器接口经常被用作匿名classes,像这样:
…
KeyListener listener = new KeyAdapter()
{
@Overwrite
void keyTyped( KeyEvent event )
{
// Do something with the event …
}
}
…
如果不使用适配器 class,相同的代码将如下所示:
…
KeyListener listener = new KeyListener()
{
@Overwrite
void keyReleased( KeyEvent event ) { /* Does nothing */ }
@Overwrite
void keyPressed( KeyEvent event ) { /* Does nothing */ }
@Overwrite
void keyTyped( KeyEvent event )
{
// Do something with the event …
}
}
…
额外的行对可读性没有帮助,不是真的。
如前所述,如果接口中的方法将提供一个空的默认实现,则第二个版本 (new
Interface()
{…}
) 看起来像第一个。
这些适配器 class 只是不包含任何抽象方法的抽象 class 的一种可能用例。但我承认,它们中的大多数在接口中使用默认方法会更好——因为这些默认方法当然进入了 Java!适配器 classes 自 Java 1.1 以来就存在,我认为......就像语言规范中的那些短语!