Java中的抽象变量?

时间:2010-03-03 12:10:10

标签: java class variables abstract

我来自c#,这很容易,而且可能。

我有这段代码:

public abstract class clsAbstractTable {

    public abstract String TAG;
    public abstract void init();

}

但Eclipse告诉我我使用非法修饰符。

我有这堂课:

public class clsContactGroups extends clsAbstractTable {


}

我希望以这种方式定义变量和方法,Eclipse要提示我,我没有实现抽象变量和方法。

我如何定义抽象类,以便提示我实现摘要?

编辑1

我将为不同的数据库表创建不同的类。每个类都应该有自己的TABLENAME变量,没有例外。每当我创建一个扩展抽象类的新类时,我必须确保这个变量是静态的。

然后在抽象类中我会有一个方法,例如:init();

如果在这个init()方法中我调用TABLENAME,它应该从子类中获取值。

这样的事情也应该解决

String tablename=(clsAbstract)objItem.TABLENAME;
// where objItem can be any class that extended clsAbstract;

编辑2

我希望在每个类中定义一个常量(静态),其名称用abstract定义。

  • 我在abstract中定义变量TABLENAME,但没有赋值。
  • 我创建了一个clsContactGroups,我应该被提示实现TABLENAME,这是获取一些数据的地方。例如:TABLENAME =“contactgroups”;
  • 我创建了第二个类clsContacts,我应该被提示实现TABLENAME,这是获取一些数据的地方。例如:TABLENAME =“contacts”;
    等...

12 个答案:

答案 0 :(得分:58)

在抽象类中定义一个构造函数,该构造函数设置字段,以便具体实现符合调用/覆盖构造函数所需的规范。

E.g。

public abstract class AbstractTable {
    protected String name;

    public AbstractTable(String name) {
        this.name = name;
    }
}

扩展AbstractTable时,在添加调用super("somename")的构造函数之前,类不会编译。

public class ConcreteTable extends AbstractTable {
    private static final String NAME = "concreteTable";

    public ConcreteTable() {
        super(NAME);
    }
}

这样,实现者需要设置name。这样,您还可以在抽象类的构造函数中执行(null)检查,以使其更加健壮。 E.g:

public AbstractTable(String name) {
    if (name == null) throw new NullPointerException("Name may not be null");
    this.name = name;
}

答案 1 :(得分:48)

我认为您的混淆是C#属性与字段/变量。在C#中,即使在抽象类中也无法定义抽象字段。但是,您可以定义抽象属性,因为这些是有效的方法(例如,编译为get_TAG()set_TAG(...))。

正如一些人提醒过的,你的类中永远不应该有公共字段/变量,即使在C#中也是如此。几个答案暗示了我的建议,但还没有说清楚。您应该使用getTAG()将您的想法转换为Java作为JavaBean属性。然后你的子类必须实现这个(我也编写了一个带有表类的项目)。

所以你可以像这样定义一个抽象类......

public abstract class AbstractTable {

    public abstract String getTag();
    public abstract void init();

    ...
}

然后,在任何具体的子类中,您需要定义一个静态最终变量(常量)并从getTag()返回,如下所示:

public class SalesTable extends AbstractTable {

    private static final String TABLE_NAME = "Sales";

    public String getTag() {
        return TABLE_NAME;
    }

    public void init() {
        ...
        String tableName = getTag();
        ...
    }

}

修改

您不能覆盖继承的字段(在C#或Java中)。你也不能覆盖静态成员,无论它们是字段还是方法。所以这也是最好的解决方案。我更改了上面的init方法示例,以显示如何使用它 - 再次,将getXXX方法视为属性。

答案 2 :(得分:6)

Java(或C ++)中没有抽象变量。

如果父类具有变量,并且子类扩展了父类,则子类不需要实现该变量。它只需要访问父实例。获取/设置或受保护的访问都可以。

“......所以我应该被提示实施摘要”?如果扩展抽象类并且无法实现抽象方法,编译器将告诉您实现它或将子类标记为抽象。这就是你得到的所有提示。

答案 3 :(得分:2)

只需将此方法添加到基类

即可
public abstract class clsAbstractTable {

    public abstract String getTAG();
    public abstract void init();

}

现在,扩展基类(并且不想抽象)的每个类都应提供TAG

您也可以使用BalusC的答案

答案 4 :(得分:2)

你能做的最好的事情就是拥有变量的访问者/变异者 类似 getTAG()的东西  这样,所有实施类都必须实现它们
抽象类用于定义抽象行为而不是数据。

答案 5 :(得分:1)

由于没有变量的实现,它不能是抽象的;)

答案 6 :(得分:1)

为什么要让所有子类定义变量?如果每个子类都应该拥有它,那么只需在超类中定义它。顺便说一句,鉴于OOP的良好做法是不要暴露字段,你的问题就更没意义了。

答案 7 :(得分:1)

将代码更改为:

public abstract class clsAbstractTable {
  protected String TAG;
  public abstract void init();
}

public class clsContactGroups extends clsAbstractTable {
  public String doSomething() {
    return TAG + "<something else>";
  }
}

这样,所有继承此类的类都将具有此变量。你可以做200个子类,但每个子类都有这个变量。

附注:不要使用CAPS作为变量名;常识是所有大写标识符都是指常量,即不可更改的数据。

答案 8 :(得分:1)

要添加每类元数据,可能注释可能是正确的方法。

但是,您无法在界面中强制执行注释,就像您无法强制执行静态成员或存在特定构造函数一样。

答案 9 :(得分:0)

使用枚举也可以强制值以保持绑定检查:

enum Speed {
    HIGH, LOW;
}
private abstract  class SuperClass {
    Speed speed;
    SuperClass(Speed speed) {
        this.speed = speed;
    }
}
private class ChildClass extends SuperClass {
    ChildClass(Speed speed) {
        super(speed);
    }
}

答案 10 :(得分:0)

在我的实验中,Java抽象类确实需要指定抽象关键字。相反,将提示“抽象修饰符不能放在此处”的错误。 您可以像普通属性一样指定抽象属性。

public abstract class Duck implements Quackable, Observable {
    // observerList should keep the list of observers watching this duck 
    List<Observer> observerList;

    public AttackBehavior attackBehavior;
    public FlyBehavior flyBehavior;

    public Duck() {
        observerList = new ArrayList<Observer>();
    }
}

在子类中,您可以直接使用这些属性this.flyBehaviorthis.attackBehavior。您无需在属性字段中重写属性。

答案 11 :(得分:-1)

不,Java不支持抽象变量。它也没有多大意义。

对于您希望子类执行的变量“实现”有哪些具体更改?

当我在基类中有一个abstract String变量时,子类应该怎么做才能使它成为非抽象的?