【问题标题】:Difference between super(variableName) ; and super.variableNamesuper(variableName) 之间的区别;和 super.variableName
【发布时间】:2019-02-20 16:33:10
【问题描述】:

super(variable-name);super.variableName = something;在构造函数中的区别是什么,当你想初始化参数并且你想将其中一个分配给父类的变量时?

例如我想实现“Zahnradfraese”的构造函数,它接受参数“int Kennung”,这个参数应该分配给父类“Produktionmittel”的属性“kennung”

当我想从这个父类调用一个变量时,我应该总是使用 super 还是如果我在子类中有另一个同名的变量就使用它?

【问题讨论】:

  • 由于无法修改kennung类,可以在Zahnradfraese类的构造函数中使用super.setKennung(kennung)

标签: java oop inheritance constructor superclass


【解决方案1】:

super(variable_name) 表示构造函数调用,应该是构造函数的第一行。而super.variableName = something; 表示您使用super 从子类中为父类的实例变量赋值,该值用于引用父类对象。

现在在您的情况下:根据给定的类图 Zahnradfraese 类有一个构造函数,它接受 int Kennung 参数。另外,kennung 是父类,没有构造函数,而是有方法setKennung()。所以你可以在Zahnradfraese 类的构造函数中做super.setKennung(kennung)。您也可以在 kennung 中声明构造函数,但这意味着偏离具有 setter 和 getter 方法且没有构造函数的类图。

public class Zahnradfraese extends Kennung{
  public Zahnradfraese(int kennung){
    super.setKennung(kennung);
  }
}

【讨论】:

  • 太棒了!谢谢,请再问一个问题,在这种情况下,如果我使用 setKennung,超级不会有什么不同吗?我的意思是因为 Zahnradfraese 正在扩展 Produktionmittel,所以它可以使用它的方法,对吧?如果我喜欢 super.kennung = sth 会做同样的工作吗?
  • @Sengo 你是对的。在您的情况下,子类可以访问父类方法,因此您可以这样做。
【解决方案2】:

super(variableName);super.variableName = something; 有什么区别?

method()(这里是super(variableName))是一个方法调用(这里是父级的构造函数调用)。

super.variableName = something; 是对父字段的赋值。

当我想从这个父类调用一个变量时我应该总是使用super,还是如果我在子类中有另一个同名的变量就使用它?

super(variableName) 可以初始化父级的内部状态,尤其是super.variableName。在访问之前初始化一个super.variableName 是合理的。您列出的两种方式都可以用于此目的。只要确保没有代码重复。

我要实现Zahnradfraese的构造函数,它接受参数int Kennung,这个参数应该赋值给父类Produktionmittel的属性kennung

Produktionmittel 添加一个构造函数,它接受int

public Produktionmittel(int i) {
    kennung = i;
}

并从孩子那里调用它:

public Zahnradfraese(int kennung) {
    super(kennung);
}

【讨论】:

  • 感谢您的回答,我不明白您所说的 super(variableName) 可以初始化父级的内部状态是什么意思。你能解释一下吗?而且我没有向 Produktionmittel 添加构造函数的选项
  • @Sengo 一个对象的内部状态是它所拥有的所有字段的状态。
  • @Sengo 单个构造函数参数可以影响多个字段(例如,它可以设置一个字段并参与另一个字段的计算)
  • @Sengo,如果不能给父级添加构造函数,那么super.variable = value;是唯一的选择。
【解决方案3】:

super(arg) 调用超类的构造函数,设置变量只是设置变量。 (构造函数可能包含更多的逻辑,而不仅仅是分配一个变量,您可以通过第二种方式绕过)

简单示例:

public class P{
  protected String variable1;
  private boolean variableInitialized = false;

  public P (String s){
     this.variable1 = s;
     this.variableInitialized=true;
  }
}

public class C extends P{

}

C 中调用super("x") 也会设置布尔标志,因为父类“可能期望”它。调用super.variable1="x" 不会影响布尔标志,你不能​​改变它,因为它是私有的。

根据经验,我会说:如果某个变量有专用的构造函数,那么似乎值得使用它,除非您确实想覆盖该实现。

【讨论】:

    【解决方案4】:

    super()是一个关键字,用于调用父类的构造函数,必须从子类的构造函数内部调用。也必须是第一个语句。

    其中super.s用于设置子类中的变量s(在父类中声明),没有上述限制。

    见下例:

    class Test {
        int s;
    
        Test(int d) {
        }
    }
    
    class T extends Test {
        T() {
            super(8);
            int d = 99;
            super.s = 00;
        }
    
        void ss() {
            super.s = 99;
        }
    }
    

    【讨论】:

    • 谢谢你的帮助,那么super(8)会编译Test类的构造函数吗?
    • @Sengo,它将执行(不编译)Test 构造函数
    【解决方案5】:

    所以super(variableName) 正在调用您的父类一个 arg 构造函数,然后执行该逻辑

    super.variableName = something; 正在将 something 值分配给父类变量 variableName

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 2019-06-07
      • 1970-01-01
      • 2011-01-08
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      相关资源
      最近更新 更多