【问题标题】:What is the correct way to initialize a member of a superclass?初始化超类成员的正确方法是什么?
【发布时间】:2012-05-27 01:50:34
【问题描述】:

如果我有一个类,例如一个在构造函数中初始化的 HashMap,像这样......

public class MySuper{
   HashMap<String,String> foo;

   public MySuper(){
      foo = new HashMap<String,String>();
   }
}

我的印象(这是不正确的)是我只需要在子类中调用 super 并且会进行相同的初始化,但是 Eclipse 对以下语法不满意...

 public class MySub extends MySuper{
      public MySub(){
         super.MySuper()
      }
   }

所以,我很好奇这样做的正确方法是什么。我是否必须在 MySuper 中创建一个单独的方法来进行初始化并调用 super ? (我知道这会起作用),但我的印象是有一种方法可以在我要扩展的类上调用 super 并让它执行它通常在其构造函数中执行的任何操作。

TIA

【问题讨论】:

  • 有人强烈反对它(荒谬),但我赞成它,所以现在它为零。希望有人会提醒那个人,曾经他/她也是初学者,就像我们所有人一样。
  • 正如其他人所说,您遇到的主要问题(除了缺少; 之外,您应该调用super 而不是super.MySuper。而且,也如上所述,您确实不需要显式调用super,除非您需要提供与子构造函数的参数列表不同的参数列表。
  • (我总是要花点时间才能记住,Java 只是 super —— 太多的语言在我脑海中转来转去,而且它们的表现各不相同。)
  • 是的......我总是对这些反对票中的一些人是多么卑鄙而感到惊讶!我的意思是......这是一个完全合理的问题,我努力表明我已经四处寻找并试图自己弄清楚,但真的......不是这个网站的全部意义在于让每个人都免于重新发明每辆自行车?碰巧,我*不是初学者......我只是不太使用 Java,并且对这里的语法很感兴趣。无论如何......我真的很感谢你的帮助!谢谢大家。
  • (抱歉跑题了,请注意@Dr.Dredel:我并不是说您通常是初学者,只是从某种意义上说您有点不熟悉Java实践-只是就像我几个月前一样,直到我需要刷新/学习它;如果一个人不使用一种语言,那么他不练习是很正常的;所以反对票的人真的是狭隘的 IMO。(话题结束)

标签: java subclassing super


【解决方案1】:

超类的无参构造函数会自动从子类调用。

但是如果你想在你的代码中强调它,你可以使用:

 public class MySub extends MySuper{
      public MySub(){
         super();
      }
   }

super() 必须是构造函数主体的第一条语句。

【讨论】:

  • 其实super不一定是第一个语句。在它之前根本不可能有任何“威胁”(唉,定义“威胁”是相当复杂的)。
【解决方案2】:

你可以只调用 super() -- 另外,在你的特定示例中,你甚至不必在子类中编写构造函数,它会隐式调用超类默认构造函数

【讨论】:

  • 等等,所以,你是说即使我不调用 super foo 也会在我的子类中初始化并准备好使用?
  • 那太棒了,但是现在我不太清楚 super() 的意义是什么,如果你除了默认构造函数之外没有任何东西。我经常在人们的代码中看到它,但是他们必须通过调用不带参数的裸超级来明确避免其他构造函数?
  • 这可能是他们的编码风格。如果您不这样做,Java 编译器会自动插入调用。
  • 如果我想用 args 显式调用超类构造函数,我通常只使用 super ...如果超类没有默认构造函数,那么你必须显式调用 super(我认为编译器会捕获这个如果你不这样做)
  • @Dr.Dredel:即使不是必要,为了便于阅读,明确和明确也是一个好习惯。
【解决方案3】:

您通常不必做任何事情。

调用子类构造函数时,会自动调用超类无参数构造函数。

如果你在超类中没有无参数构造函数,或者你想调用另一个重载版本,那么你必须通过super显式调用(否则你的代码将无法编译,因为超类构造函数有被调用,并且如果默认的无参数构造函数不可用,VM 将不知道调用哪个重载)。

你这样做:

super()

 public class MySub extends MySuper{
      public MySub(){
         super();
      }
   }

 public class MySub extends MySuper{
      public MySub(int a, int b){
         super(a, b);
      }
   }

using super.

【讨论】:

    【解决方案4】:
    You have no need to call super.MySuper() because super classe's default constructor always invoke implicitly because the first line of child class's constructor is super() by default.
    
    public class MySuper{
       HashMap<String,String> foo;
    
       public MySuper(){
          foo = new HashMap<String,String>();
       }
    }
    
    public class MySub extends MySuper{
    
    }
    

    【讨论】:

      【解决方案5】:

      默认情况下,子类的默认构造函数会调用超类的默认构造函数,所以你可以直接写

      public MySub(){
          // super(); is automatically called at first line, so you no need call it
          // child init
      }
      

      或者你可以在子构造函数的第一行调用超类的构造函数

      public MySub(){
          super();
          // child init
      }
      

      如果超类有你想调用的构造函数public MySuper(int i),你可以写

      public MySub(){
          super(100);
          // child init
      }
      

      【讨论】:

      • 如果要在子构造函数中包含代码,则应在第一行添加super()语句。
      猜你喜欢
      • 1970-01-01
      • 2018-11-24
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多