Java中的抽象变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2371025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Abstract variables in Java?
提问by Pentium10
I am coming from c# where this was easy, and possible.
我来自 c#,这很容易,而且可能。
I have this code:
我有这个代码:
public abstract class clsAbstractTable {
public abstract String TAG;
public abstract void init();
}
but Eclipse tells me I use illegal modifier.
但是 Eclipse 告诉我我使用了非法修饰符。
I have this class:
我有这门课:
public class clsContactGroups extends clsAbstractTable {
}
I want the variable and method defined in such way, that Eclipse to prompt me, I have unimplemented abstract variablesand methods.
我希望以这种方式定义变量和方法,以便 Eclipse提示我,我有未实现的抽象变量和方法。
How do I need to define my abstract class so I should be prompted to implement the abstracts?
我需要如何定义我的抽象类,以便提示我实现抽象?
EDIT 1
编辑 1
I will create different classes for different db tables. Each class should have it's own TABLENAME variable, no exception. I have to make sure this variable is static each time when I create a new class that extends the abstract class.
我将为不同的数据库表创建不同的类。每个类都应该有它自己的 TABLENAME 变量,也不例外。每次创建扩展抽象类的新类时,我都必须确保此变量是静态的。
Then in the abstract class I will have a method eg: init();
然后在抽象类中,我将有一个方法,例如:init();
If in this init() method I call TABLENAME, it should take the value from the sub-class.
如果在这个 init() 方法中我调用 TABLENAME,它应该从子类中获取值。
something like this should also work out
这样的事情也应该解决
String tablename=(clsAbstract)objItem.TABLENAME;
// where objItem can be any class that extended clsAbstract;
EDIT 2
编辑 2
I want a constant(static) defined in each class having it's name defined in abstract.
我想要在每个类中定义一个常量(静态),并在抽象中定义它的名称。
- I define variable TABLENAME in abstract, but no value given.
- I create a clsContactGroups, I should be prompted to implement TABLENAME, this is where gets some data. eg: TABLENAME="contactgroups";
- I create a second class clsContacts, I should be prompted to implement TABLENAME, this is where gets some data. eg: TABLENAME="contacts";
etc...
- 我抽象地定义了变量 TABLENAME,但没有给出值。
- 我创建了一个 clsContactGroups,应该会提示我执行 TABLENAME,这是获取一些数据的地方。例如:TABLENAME="联系人组";
- 我创建了第二个类 clsContacts,应该会提示我执行 TABLENAME,这是获取一些数据的地方。例如:TABLENAME="联系人";
等等...
采纳答案by Kevin Brock
I think your confusion is with C# properties vs. fields/variables. In C# you cannot define abstract fields, even in an abstract class. You can, however, define abstract properties as these are effectively methods (e.g. compiled to get_TAG()
and set_TAG(...)
).
我认为您的困惑在于 C# 属性与字段/变量。在 C# 中,您不能定义抽象字段,即使在抽象类中也是如此。但是,您可以定义抽象属性,因为它们是有效的方法(例如编译为get_TAG()
和set_TAG(...)
)。
As some have reminded, you should never have public fields/variables in your classes, even in C#. Several answers have hinted at what I would recommend, but have not made it clear. You should translate your idea into Java as a JavaBean property, using getTAG(). Then your sub-classes will have to implement this (I also have written a project with table classes that do this).
正如一些人所提醒的那样,即使在 C# 中,也不应该在类中使用公共字段/变量。有几个答案暗示了我的建议,但没有说清楚。您应该使用 getTAG() 将您的想法作为 JavaBean 属性转换为 Java。然后你的子类将不得不实现这一点(我也编写了一个带有执行此操作的表类的项目)。
So you can have an abstract class defined like this...
所以你可以有一个像这样定义的抽象类......
public abstract class AbstractTable {
public abstract String getTag();
public abstract void init();
...
}
Then, in any concrete subclasses you would need to define a static final variable (constant) and return that from the getTag()
, something like this:
然后,在任何具体的子类中,您都需要定义一个静态最终变量(常量)并从 返回它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();
...
}
}
EDIT:
编辑:
You cannot override inherited fields (in either C# or Java). Nor can you override static members, whether they are fields or methods. So this also is the best solution for that. I changed my init method example above to show how this would be used - again, think of the getXXX method as a property.
您不能覆盖继承的字段(在 C# 或 Java 中)。您也不能覆盖静态成员,无论它们是字段还是方法。所以这也是最好的解决方案。我更改了上面的 init 方法示例以展示如何使用它 - 再次将 getXXX 方法视为一个属性。
回答by Tomas Vana
As there is no implementation of a variable it can't be abstract ;)
由于没有变量的实现,它不能是抽象的;)
回答by Joachim Sauer
No, Java doesn't support abstract variables. It doesn't really make a lot of sense, either.
不,Java 不支持抽象变量。这也没有多大意义。
What specific change to the "implementation" of a variable to you expect a sub class to do?
您期望子类对变量的“实现”进行哪些具体更改?
When I have a abstract
String
variable in the base class, what should the sub class do to make it non-abstract?
当我abstract
String
在基类中有一个变量时,子类应该怎么做才能使它成为非抽象的?
回答by duffymo
No such thing as abstract variables in Java (or C++).
Java(或C++)中没有抽象变量之类的东西。
If the parent class has a variable, and a child class extends the parent, then the child doesn't need to implement the variable. It just needs access to the parent's instance. Either get/set or protected access will do.
如果父类有一个变量,子类继承了父类,那么子类就不需要实现这个变量。它只需要访问父级的实例。get/set 或 protected 访问都可以。
"...so I should be prompted to implement the abstracts"? If you extend an abstract class and fail to implement an abstract method the compiler will tell you to either implement it or mark the subclass as abstract. That's all the prompting you'll get.
“......所以我应该被提示实现摘要”?如果您扩展抽象类但未能实现抽象方法,编译器会告诉您要么实现它,要么将子类标记为抽象。这就是你会得到的所有提示。
回答by BalusC
Define a constructor in the abstract class which sets the field so that the concrete implementations are per the specification required to call/override the constructor.
在设置字段的抽象类中定义一个构造函数,以便具体实现符合调用/覆盖构造函数所需的规范。
E.g.
例如
public abstract class AbstractTable {
protected String name;
public AbstractTable(String name) {
this.name = name;
}
}
When you extend AbstractTable
, the class won't compile until you add a constructor which calls super("somename")
.
当您扩展时AbstractTable
,该类将不会编译,直到您添加一个调用super("somename")
.
public class ConcreteTable extends AbstractTable {
private static final String NAME = "concreteTable";
public ConcreteTable() {
super(NAME);
}
}
This way the implementors are required to set name
. This way you can also do (null)checks in the constructor of the abstract class to make it more robust. E.g:
通过这种方式,实现者需要设置name
. 通过这种方式,您还可以在抽象类的构造函数中进行(空)检查以使其更加健壮。例如:
public AbstractTable(String name) {
if (name == null) throw new NullPointerException("Name may not be null");
this.name = name;
}
回答by Lombo
Just add this method to the base class
只需将此方法添加到基类
public abstract class clsAbstractTable {
public abstract String getTAG();
public abstract void init();
}
Now every class that extends the base class (and does not want to be abstract) should provide a TAG
现在每个扩展基类(并且不想抽象)的类都应该提供一个 TAG
You could also go with BalusC's answer
您也可以使用 BalusC 的答案
回答by Padmarag
The best you could do is have accessor/mutators for the variable.
Something like getTAG()
That way all implementing classes would have to implement them.
Abstract classes are used to define abstract behaviour not data.
您能做的最好的事情就是为变量设置访问器/修改器。
像getTAG()
这样的所有实现类都必须实现它们。
抽象类用于定义抽象行为而非数据。
回答by Erich Kitzmueller
Why do you want all subclasses to define the variable? If every subclass is supposed to have it, just define it in the superclass. BTW, given that it's good OOP practice not to expose fields anyway, your question makes even less sense.
为什么要让所有子类都定义变量?如果每个子类都应该拥有它,只需在超类中定义它。顺便说一句,鉴于无论如何都不公开字段是好的 OOP 实践,您的问题更没有意义。
回答by dimitarvp
Change the code to:
将代码更改为:
public abstract class clsAbstractTable {
protected String TAG;
public abstract void init();
}
public class clsContactGroups extends clsAbstractTable {
public String doSomething() {
return TAG + "<something else>";
}
}
That way, all of the classes who inherit this class will have this variable. You can do 200 subclasses and still each one of them will have this variable.
这样,所有继承这个类的类都会有这个变量。您可以创建 200 个子类,并且每个子类都将具有此变量。
Side note: do not use CAPS as variable name; common wisdom is that all caps identifiers refer to constants, i.e. non-changeable pieces of data.
旁注:不要使用大写字母作为变量名;常识是所有大写标识符都指代常量,即不可更改的数据片段。
回答by Joachim Sauer
To add per-class metadata, maybe an annotation might be the correct way to go.
要添加每个类的元数据,注解可能是正确的方法。
However, you can't enforce the presence of an annotation in the interface, just as you can't enforce static members or the existence of a specific constructor.
但是,您不能强制在接口中存在注释,就像您不能强制静态成员或特定构造函数的存在一样。