抽象类 - 请澄清

时间:2014-07-12 16:13:19

标签: java

我阅读了关于抽象类的教程,对某些事情有点不清楚。

我有一个抽象类

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 */
}

我的问题

  1. 特定于FirstMaster和SecondMaster的静态变量p和JFrame,即Master.p,FirstMaster.p和SecondMaster.p是具有单个内存位置的同一个Point吗?
  2. 第一个和第二个Master的每个(实例)是一个独立的ActionListener,需要定义相关的方法 - 正确吗?
  3. 如果没有修饰符静态,它就等同于简单地将Master中的代码复制并粘贴到First和Second中并摆脱扩展?
  4. 很抱歉新手问题,但我没有看到一个明确解决问题的例子。

    编辑:由于下面有很多信息,我想我会总结一下我对答案的理解,以便后续读者受益(如果我弄错了,请纠正)

    1. 只有一个p。扩展不会为每个子类创建一个新的静态p,这个事实与abstract修饰符无关。
    2. 方法actionPerformed()可以在Master中指定,也可以在BOTH First和Second定义中指定。在First和Second中指定它允许对操作的响应对每个子类都是唯一的。
    3. 忽略实现ActionListener的复杂性,答案是肯定的,尽管这会导致冗余代码。
    4. 感谢所有人。

3 个答案:

答案 0 :(得分:2)

问题1:当您在顶级类中声明static成员对象(字段)时,整个程序中只有一个对象,句点。如果对象为x并且它在类Class1中,则Class1.x将引用该对象。如果你有一个扩展Class2的子类Class1Class2.x是引用同一个对象的另一种方式,如果x没有被另一个其他声明隐藏x {1}}。但是没有为子类创建新的静态对象。这些都不取决于这些类是否是抽象的。

问题2:在ActionListener中声明的任何方法都需要通过编写方法的实体来实现。您可以在Master中实现它们。无论您在Master中未实施哪种方法,都需要在FirstMasterSecondMaster中实施。如果您在Master中实施它们, 仍然可以在FirstMasterSecondMaster中编写覆盖方法,但如果不这样做,它们将继承这些方法你在Master写道。我不确定“每个实例”必须定义相关方法的含义;你必须在每个(非抽象)子类中定义它。

问题3:摆脱extends会创建一个完全不同的程序。你编写它的方式,如果你有一个需要ActionListener的方法:

public void addListener(ActionListener listener);

您可以向其传递FirstMasterSecondMaster的实例,因为这些类的实例也是ActionListener的间接实例。如果你摆脱extends Master,你就不能这样做。即使您摆脱extends Master并添加implements ActionListener,您也无法再编写类似

的方法
public void addMasterListener(Master m);

为了编写这样的方法并让它工作,您需要能够传递FirstMasterSecondMaster的实例。所以(正如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,包括FirstMasterSecondMasterglass也是如此。

这是因为pglass被声明为“package protected”,因为你private,{{1} }或protected之前(如public)。受保护的包只能由同一包中的类使用(子类或非子类)。 public Point p只能由子类使用。

  

第一个和第二个Master的每个(实例)是一个独立的ActionListener,需要定义相关的方法 - 正确吗?

“相关方法”?你指的是什么方法?如果protected基类中有抽象方法,那么是的,所有孩子都需要定义该方法。

更准确地说MasterFirstMaster的“每个定义”必须定义抽象方法。在正常情况下,实例不会定义方法。

  

如果没有修饰符静态,它就等同于简单地将Master中的代码复制并粘贴到First和Second中并摆脱扩展?

嗯,超类的潜在有益副作用是避免使用冗余代码。在一个很小的项目中,就像这个小例子一样,这种冗余很小,并且可以很容易地保留复制粘贴。

在一个中等规模的项目中,冗余代码可以使项目停止运行。

因此,从设计的角度来看,我总是选择使用超类(或其他形式或防止冗余代码,例如实用程序类)。我很少选择冗余代码。这是因为项目通常比你意识到的要大,而且你不希望在项目的整个生命周期中遇到短视的设计决定。