我阅读了关于抽象类的教程,对某些事情有点不清楚。
我有一个抽象类
abstract class Master implements ActionListener {
static Point p;
static JFrame glass;
/* code to define glass and a mouseListener to it.
The mouselistener essentially registers the mouseclick
and point P where it happened */
}
我延伸了其他人
class FirstMaster extends Master {
/* some definitions and stuff */
}
class SecondMaster extends Master {
/* some definitions and stuff */
}
我的问题
很抱歉新手问题,但我没有看到一个明确解决问题的例子。
编辑:由于下面有很多信息,我想我会总结一下我对答案的理解,以便后续读者受益(如果我弄错了,请纠正)
感谢所有人。
答案 0 :(得分:2)
问题1:当您在顶级类中声明static
成员对象(字段)时,整个程序中只有一个对象,句点。如果对象为x
并且它在类Class1
中,则Class1.x
将引用该对象。如果你有一个扩展Class2
的子类Class1
,Class2.x
是引用同一个对象的另一种方式,如果x
没有被另一个其他声明隐藏x
{1}}。但是没有为子类创建新的静态对象。这些都不取决于这些类是否是抽象的。
问题2:在ActionListener
中声明的任何方法都需要通过编写方法的实体来实现。您可以在Master
中实现它们。无论您在Master
中未实施哪种方法,都需要在FirstMaster
和SecondMaster
中实施。如果您在Master
中实施它们, 仍然可以在FirstMaster
或SecondMaster
中编写覆盖方法,但如果不这样做,它们将继承这些方法你在Master
写道。我不确定“每个实例”必须定义相关方法的含义;你必须在每个(非抽象)子类中定义它。
问题3:摆脱extends
会创建一个完全不同的程序。你编写它的方式,如果你有一个需要ActionListener
的方法:
public void addListener(ActionListener listener);
您可以向其传递FirstMaster
或SecondMaster
的实例,因为这些类的实例也是ActionListener
的间接实例。如果你摆脱extends Master
,你就不能这样做。即使您摆脱extends Master
并添加implements ActionListener
,您也无法再编写类似
public void addMasterListener(Master m);
为了编写这样的方法并让它工作,您需要能够传递FirstMaster
或SecondMaster
的实例。所以(正如Thomas Uhrig评论的那样),使用extends
是一种通过使用多态来改进程序的方法,而不仅仅是一种避免代码重复的方法。
答案 1 :(得分:1)
静态变量p和JFrame是否特定于FirstMaster和SecondMaster
是的,他们将在该内存位置保持覆盖值。
第一和第二主人的每个(实例)都是独立的 ActionListener并需要定义相关的方法 - 正确吗?
如果你想说第一和第二主人是否需要定义相关方法?如果方法的实现是用抽象类编写的,那么在这种情况下,第一个master和第二个master不需要定义那个方法但是如果那是一个抽象方法(没有或不完整的实现的方法)那么两个都是First和第二位大师将有自己的方法实现。
如果没有修饰符静态,它就等同于简单地将Master中的代码复制并粘贴到First和Second中并摆脱扩展?
是的,我们使用抽象类当你需要一个类来实现继承和多态时,抽象类是有用的,但实例化类本身,只有它的子类并且它可以在类中实现某些功能是没有意义的。它删除了扩展它的类中的样板代码。
答案 2 :(得分:1)
FirstMaster和SecondMaster特有的静态变量p和JFrame,即Master.p,FirstMaster.p和SecondMaster.p是具有单个内存位置的同一个Point吗?
所有p
共享一个Master
,包括FirstMaster
和SecondMaster
。 glass
也是如此。
这是因为p
和glass
被声明为“package protected”,因为你不放private
,{{1} }或protected
之前(如public
)。受保护的包只能由同一包中的类使用(子类或非子类)。 public Point p
只能由子类使用。
第一个和第二个Master的每个(实例)是一个独立的ActionListener,需要定义相关的方法 - 正确吗?
“相关方法”?你指的是什么方法?如果protected
基类中有抽象方法,那么是的,所有孩子都需要定义该方法。
更准确地说Master
和FirstMaster
的“每个定义”必须定义抽象方法。在正常情况下,实例不会定义方法。
如果没有修饰符静态,它就等同于简单地将Master中的代码复制并粘贴到First和Second中并摆脱扩展?
嗯,超类的潜在有益副作用是避免使用冗余代码。在一个很小的项目中,就像这个小例子一样,这种冗余很小,并且可以很容易地保留复制粘贴。
在一个中等规模的项目中,冗余代码可以使项目停止运行。
因此,从设计的角度来看,我总是选择使用超类(或其他形式或防止冗余代码,例如实用程序类)。我很少选择冗余代码。这是因为项目通常比你意识到的要大,而且你不希望在项目的整个生命周期中遇到短视的设计决定。