我从名为ChildClass
的抽象类扩展,它有4个应该实现的构造函数。
所有构造函数都有一组通用配置
我可以抽象出这些任务并在所有构造函数中调用它
无论如何在初始化对象时调用一个指定方法而不是在所有构造函数签名中调用它?
答案 0 :(得分:3)
由于Java编译器必须确保调用基类的构造函数,因此可以将公共代码放在抽象基类的构造函数中:
abstract class BaseClass {
protected BaseClass(/*put arguments here*/) {
// Code that is common to all child classes
}
}
class ChildClassOne extends BaseClass {
public ChildClassOne(/*put arguments here*/) {
super(arg1, arg2, ...);
// More code here
}
}
答案 1 :(得分:1)
您可以在类中声明一个可以从构造函数中调用的实例方法,如下所示:
class Helper {
static var originalModel: [MyModel]? = nil
static func modifyDataSourceBigView () -> [MyModel]? {
if var model = originalModel{
model.remove(at: 0)
// Some other staff to adapt the model
return model
}
return nil
}
static func modifyDataSourceSmallView () -> [MyModel]? {
if var model = originalModel {
model.remove(at: 0)
// Some other staff to adapt the model
return model
}
return nil
}
}
这个概念也扩展到抽象类。
答案 2 :(得分:1)
你可以链接你的构造函数。
public class Test {
public Test() {
// Common initialisations.
}
public Test(String stuff) {
// Call the one ^
this();
// Something else.
}
然后,您可以将公共代码放在()
构造函数中。
答案 3 :(得分:1)
正如评论中已经说过的,调用常见初始化代码的一种方法是使用'Q'
,即你从另一个调用一个构造函数。然而,问题是这个调用必须是构造函数的第一个语句,因此可能无法提供你想要的东西。
或者,您可以在所有构造函数和适当的位置(例如,在构造函数的末尾)调用一些初始化方法(最常见的名称为this(...)
)。但是有一个问题:如果子类会覆盖该方法,则可能会创建未定义的情况,其中超级构造函数调用该方法,并且该方法使用子类的非初始化字段。为了减轻该方法不应该被覆盖,即宣布它是最终的或将其设为私有(我更喜欢让它最终,因为它更明确)。
根据您的需要,还有第三种选择:使用初始化程序块:
init()
以下是结合所有3个选项的示例:
class Super {
{
//this is the initializer block that is called before the corresponding constructors
//are called so it might or might not fit your needs
}
}
如果您现在致电static class Super {
{
//called before any of the Super constructors
System.out.println( "Super initializer" );
}
private final void init() {
System.out.println( "Super init method" );
}
public Super() {
System.out.println( "Super common constructor" );
}
public Super(String name) {
this(); //needs to be the first statement if used
System.out.println( "Super name constructor" );
init(); //can be called anywhere
}
}
static class Sub extends Super {
{
//called before any of the Sub constructors
System.out.println( "Sub initializer" );
}
private final void init() {
System.out.println( "Sub init method" );
}
public Sub() {
System.out.println( "Sub common constructor" );
}
public Sub(String name) {
super( name ); //needs to be the first statement if used, calls the corrsponding Super constructor
System.out.println( "Sub name constructor" );
init(); //can be called anywhere
}
}
,您将获得以下输出:
new Sub("some name")
答案 4 :(得分:0)
另一种方法是使用Initializer block。
Class A {
{
// initialize your instance here...
}
// rest of the class...
}
编译器将确保在任何构造函数之前调用初始化程序代码。
但是,我会犹豫一下使用它 - 也许只有在没有其他可能的替代方法时(比如将代码放在基类中)。
答案 5 :(得分:0)
如果您可以将公共代码放在一个构造函数中并将其作为作为来自其他构造函数的第一条指令,则它是Java惯用方法。
如果您的用例更复杂,您可以从构造函数调用特定方法,前提是它是私有的,最终的或静态的(非超支)。一个示例用例是:
class Test {
private final void init(int i, String str) {
// do common initialization
}
public Test(int i) {
String str;
// do complex operations to compute str
init(i, str); // this() would not be allowed here, because not 1st statement
}
public Test(int i, String str) {
init(i, str);
}
}
答案 6 :(得分:0)
制作一个通用方法并将其分配给实例变量。另一种方法。
import java.util.List;
public class Test {
int i = commonMethod(1);
Test() {
System.out.println("Inside default constructor");
}
Test(int i) {
System.out.println("Inside argument Constructor ");
}
public int commonMethod(int i) {
System.out.println("Inside commonMethod");
return i;
}
public static void main(String[] args) {
Test test1 = new Test();
Test test2 = new Test(2);
}
}