类-Java中的抽象变量?

我来自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

我想要在每个类中定义的常量(静态),其名称以抽象的形式定义。

我抽象地定义了变量TABLE NAME,但未提供任何值。

我创建了一个clsContactGroups,应该提示我实现TABLENAME,这是在其中获取一些数据的地方。 例如:TABLENAME =“ contactgroups”;

我创建第二个类clsContacts,应提示我实现TABLENAME,这是在其中获取一些数据的地方。 例如:TABLENAME =“ contacts”;

等等...

12个解决方案

58 votes

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

例如。

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

扩展name时,该类只有在添加调用super("somename")的构造函数后才会编译。

public class ConcreteTable extends AbstractTable {
private static final String NAME = "concreteTable";
public ConcreteTable() {
super(NAME);
}
}

这样,实现者就需要设置name。这样,您还可以在抽象类的构造函数中进行(空)检查,以使其更可靠。 例如:

public AbstractTable(String name) {
if (name == null) throw new NullPointerException("Name may not be null");
this.name = name;
}
BalusC answered 2020-07-12T21:53:07Z
49 votes

我认为您对C#属性与字段/变量的困惑是。 在C#中,即使在抽象类中,也无法定义抽象字段。 但是,您可以定义抽象属性,因为它们是有效的方法(例如,编译为getTag()和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方法视为属性。

Kevin Brock answered 2020-07-12T21:52:34Z

7 votes

没有Java(或C ++)中的抽象变量这样的东西。

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

“ ...因此应提示我实施摘要”? 如果扩展抽象类而未能实现抽象方法,则编译器会告诉您实现它或将子类标记为抽象。 这就是所有提示。

duffymo answered 2020-07-12T21:53:36Z

2 votes

只需将此方法添加到基类

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

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

您也可以使用BalusC的答案

Lombo answered 2020-07-12T21:54:05Z

2 votes

您能做的最好的事情就是为变量设置访问器/变量。

类似于getTAG()

这样,所有实现类都必须实现它们。

抽象类用于定义抽象行为而非数据。

Padmarag answered 2020-07-12T21:54:37Z

1 votes

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

Tomas Vana answered 2020-07-12T21:54:57Z

1 votes

为什么要所有子类都定义变量? 如果每个子类都应该拥有它,则只需在超类中对其进行定义。 顺便说一句,鉴于良好的OOP做法是不公开任何字段,因此您的问题变得毫无意义。

Erich Kitzmueller answered 2020-07-12T21:55:17Z

1 votes

将代码更改为:

public abstract class clsAbstractTable {
protected String TAG;
public abstract void init();
}
public class clsContactGroups extends clsAbstractTable {
public String doSomething() {
return TAG + "";
}
}

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

旁注:请勿将CAPS用作变量名; 通常的看法是,所有大写字母标识符都引用常量,即不可更改的数据。

dimitarvp answered 2020-07-12T21:55:46Z

1 votes

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

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

Joachim Sauer answered 2020-07-12T21:56:10Z

0 votes

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

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);
}
}
user531069 answered 2020-07-12T21:56:30Z
0 votes

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

public abstract class Duck implements Quackable, Observable {
// observerList should keep the list of observers watching this duck
List observerList;
public AttackBehavior attackBehavior;
public FlyBehavior flyBehavior;
public Duck() {
observerList = new ArrayList();
}
}

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

Shark Deng answered 2020-07-12T21:56:55Z

-1 votes

不,Java不支持抽象变量。 这也不是很有意义。

您期望子类对变量的“实现”进行哪些具体更改?

当我在基类中具有abstract String变量时,子类应如何使它变得非抽象?

Joachim Sauer answered 2020-07-12T21:57:24Z