我试图找出如何在任何子类中访问/使用抽象类的字段/方法,我在网上看到了这个例子。
abstract class Instrument {
protected String name;
abstract public void play();
}
abstract class StringedInstrument extends Instrument {
protected int numberOfStrings;
}
以具体示例子类为
public class ElectricGuitar extends StringedInstrument {
public ElectricGuitar() {
super();
this.name = "Guitar";
this.numberOfStrings = 6;
}
public ElectricGuitar(int numberOfStrings) {
super();
this.name = "Guitar";
this.numberOfStrings = numberOfStrings;
}
@Override
public void play() {
System.out.println("An electric " + numberOfStrings + "-string " + name
+ " is rocking!");
}
}
我有5个与此相关的问题 - 对于提出多个问题感到遗憾,但这些问题非常相关。
答案 0 :(得分:3)
super()调用是否需要甚至有效?抽象超类中没有给出构造函数。
如果你遗漏它,它会隐式调用没有参数的super()。
如果要调用带参数的超类构造函数,则显式调用可能很有用。
抽象类是否可以使用构造函数,因为它无法实例化?
是。因为仍然需要构建具体类的那部分。
是关键字" this"关于this.name的这个例子中有必要吗?
没有。有时可以消除编译器或人类读者的歧义。
这里有什么游戏()覆盖?如果在抽象类中指定了抽象方法,那么只告诉编译器该方法必须由任何子类指定?
注释允许编译器验证子类实际上是否覆盖了超类中的方法。在方法名称或签名中容易出错,并且意外地不覆盖任何方法。
当您打算覆盖抽象方法时,这有助于编译器直接指出错误。
当您打算覆盖具体方法时,这会提供编译器错误,否则该错误将不存在。这可以显着减少我们的困惑,惊讶和脱发。
如果Instrument类,StringedInstrument类和ElectricGuitar类都指定了所有指定字段" name"并且每个都指定了构造函数(如果允许),如何在ElectricGuitar类定义中访问每个名称或构造函数。
理想情况下,您希望在基类Instrument中提供单个私有字段,通过基类中定义的访问者getName()
访问。
也就是说,可以通过强制转换来访问受保护的超类字段。 注意:通常这是要避免的事情。
ElectricGuitar guitar = new ElectricGuitar();
String guitarName = guitar.name;
String stringInstrumentName = ((StringedInstrument) guitar).name;
String instrumentName = ((Instrument) guitar).name;
答案 1 :(得分:3)
super()调用是否需要甚至有效?
不需要,但它有效。所有构造函数都必须显式调用超类构造函数,或者隐式调用。如果未明确包含super();
,则编译器会为您插入隐式调用。
抽象类是否可以使用构造函数,因为它无法实例化?
是的,抽象类可以有一个构造函数。它需要由任何子类构造函数调用。
是关键字" this"关于this.name的这个例子中有必要吗?
"这"这里没有必要,因为范围中没有本地变量或参数,它们会隐藏实例变量name
。
这里有什么游戏()覆盖?
正在实施abstract
play()
方法。 @Override
注释可用于指示该方法覆盖或实现超类或接口方法。由于ElectricGuitar
不是abstract
,因此需要实施play()
,因此此处@Override
并非绝对必要。但是,最好将此注释包含在所有旨在覆盖/实现方法的方法中,以便拼写错误或拼写错误并不意味着该方法不会覆盖其他方法。 / p>
如果Instrument类,StringedInstrument类和ElectricGuitar类都指定了所有指定字段" name"并且每个都指定了构造函数(如果允许)在ElectricGuitar类定义中如何访问每个名称或构造函数?
您无法直接访问隐藏在超类上方的字段。您可以使用StringedInstrument
访问name
super.name
,但无法使用Instrument
访问name
super.super.name
,因为你不能"链" super
引用。要直接访问它们,请以不同方式命名。
但是,您可以在每个班级中提供不同名称的getter方法,以便提供对每个班级name
方法的访问权限。
答案 2 :(得分:0)
super()
以防其他开发人员定义默认构造函数并初始化其中的内容。你不想错过它。overriding
。您只需为抽象类提供实现。抽象类中的方法只是一个契约。但是你必须在具体的类中实现它。你的最后一句是对的。如果您没有任何实施,则无法调用此方法,因此不会导致问题。