Can you declare an abstract variable type in an abstract class? I am receiving an error when I put this line of code in. I can declare a variable that is final and not final but I am not sure if I should be able to declare a variable that is abstract. What would be the real advantage between an interface and an abstract class?
Error Code:
abstract int myScore = 100; <-- Causes an error
Code:
public abstract class GraphicObject {
int home = 100;
String myString = "";
final int score = 0;
abstract void draw();
abstract void meMethod1();
abstract void meMethod2();
int meMethod3() {
return 0;
}
}
"Can you declare an abstract variable type in an abstract class?"
No, according to the JLS (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1).
Why should it be abstract if you can't implement variables?
Abstract methods only mean that they must be implemented further in your code (by a class that extends that abstract class).
For variable that won't make any since they keep being the same type. myscore will always be an int.
You may be tinking about override the value of myscore by the class that extends that abstract class.
An abstract method is a method that doesn't have a body. This is because it's meant to be overridden in all concrete (non-abstract) subclasses and, thanks to polymorphism, the abstract stub can never be invoked.
Given the above, and since there is no polymorphism for fields (or a way to override fields at all), an abstract field would be meaningless.
If what you want to do is have a field whose default value is different for every subclass, then you can assign its default value in the constructor(s) of each class. You don't need to make it abstract in order to do this.
No, abstract is used so that methods can only be implemented in subclasses. See http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
You cannot declare an abstract variable in Java.
If you wish to declare a variable in a super-class, which must be set by its sub-classes, you can define an abstract method to set that value...
For example:
public abstract class Foo {
Object obj;
public Foo() {
init();
}
protected void init() {
obj = getObjInitVal();
}
abstract protected Object getObjInitVal();
}
public class Bar extends Foo {
#Override
protected Object getObjInitVal() {
return new Object();
}
}
Base on "AlonL" reply :
You can do this too
public abstract class Foo {
Object obj;
public Foo() {
init();
}
abstract protected void init();
}
public class Bar extends Foo {
#Override
protected void init() {
obj = new Object();
}
}
Related
Consider an interface and its implementation,
interface A {
int a;
default void add() {
a = a+10;
}
public void sub();
}
class X implements A {
public sub() {
a = a-5;
}
}
I have to use the variable a in sub() function of class X. How can I do?
All variables declared inside interface are implicitly public static final variables(constants).
From the Java interface design FAQ by Philip Shaw:
Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
Since interface doesn't have a direct object, the only way to access them is by using a class/interface and hence that is why if interface variable exists, it should be static otherwise it wont be accessible at all to outside world. Now since it is static, it can hold only one value and any classes that implements it can change it and hence it will be all mess.
Hence if at all there is an interface variable, it will be implicitly static, final and obviously public!!!
The field a in the interface A always final and static and it isn't supposed to be modified in any way including reassigning it in an instance method.
Interfaces don't have the state. Abstract classes may.
abstract class A {
protected int a;
public void add() {
a += 10;
}
public abstract void sub();
}
final class X extends A {
public void sub() {
a -= 5;
}
}
I would use an abstract class instead of an interface. That way the variable can be modified by the extending class.
abstract class A{
int a=10;
void add(){
a=a+10;
}
public abstract void sub();
}
class X extends A{
public void sub(){
a=a-5;
}
}
Yes, We can use abstract class.
Since in interface variables declared are by default final.
Code with Interface
Code with Abstract Class
I went to an interview. Interviewer asked me if one can instantiate an interface and abstract class? As per my knowledge I said "No". But he said "Yes, we can with the help of an anonymous class".
Can you please explain to me how?
This was a trick questions.
No you can not instantiate an interface or abstract class.
But you can instantiate an anonymous class that implements/extends the interface or abstract class without defining a class object. But it is just a shortcut to defining a fully named class.
So I would say technically your answer was correct.
I don't know what is "instantiation of interface and abstract class".
I think it's an inaccurate, improper expression of something,
we can only guess at the intended meaning.
You cannot create an instance of an interface or an abstract class in Java.
But you can create anonymous classes that implement an interface or an abstract class.
These won't be instances of the interface or the abstract class.
They will be instance of the anonymous class.
Here's an example iterator from the Iterator interface that gives you an infinity of "not really":
new Iterator<String>() {
#Override
public boolean hasNext() {
return true;
}
#Override
public String next() {
return "not really";
}
};
Or a funky AbstractList that contains 5 "not really":
List<String> list = new AbstractList<String>() {
#Override
public int size() {
return 5;
}
#Override
public String get(int index) {
return "yes";
}
};
Assume you have an abstract class: MyAbstractClass with abstract void method myAbstractMethod. Then you can make an "instance" of this class via this code:
MyAbstractClass myAbstractClassInstance = new MyAbstractClass() {
public void myAbstractMethod() {
// add abstract method implementation here
}
};
myAbstractClassInstance extends your MyAbstractClass in this case. When you instantiate this class you have to implement all abstract methods as you can see from the code above.
The same way works for interfaces, assume you have an interface MyInterface with a void method myInterfaceMethod inside, then you can create an "instance" (implementation of this instance) via this code:
MyInterface myInterfaceImpl = new MyInterface() {
public void myInterfaceMethod() {
// add method implementation here
}
}
myInterfaceImpl is an implemetation of MyInterface in this case. When you create an object using interface, you have to implement interface methods as it is shown above.
Interface :
interface Interface1 {
public void m1();
}
When you right
new Interface1() {
public void m1() {
}
}
Its not actually creating the instance of Interface. Its creating an instance of its subtype which doesnt have any name/reference. Hence we cannot create an instance of interface or abstract class
You cannot create instances of abstract classes or interfaces using the new operator. For example,
new AbstractSet(); // That's wrong.
You can, however, use them to declare reference variables. For example, You can do this:
AbstractSet set;
You can instantiate anonymous as well as declared implementing classes or subclass.
For example, Set extends AbstractSet, so you can instantiate Set.
Yes, we can create by having defining the abstract methods or the interface methods on the fly during instantiation. That's like a Named anonymous class.
//interface
Runnable r = new Runnable(){
public void run() {
System.out.println("Here we go");
}
};
//Abstract class
abstract class MyAbstract {
abstract void run();
}
MyAbstract ab = new MyAbstract(){
#Override
void run() {
System.out.println("Here we go");
}};
I have a base class and subclass. Base class has common methods and its implementation which I want to use in subclass but I want to use subclass member variable instead of superclass. I do not want to rewrite the same method in subclass. Is there a way in Java to achieve this.
You could create a protected setter on the member variable & then override the value of the super's variable within the constructor of the subclass:
class Animal {
private String voice = "Oooo";
protected void setVoice(String voice) {
this.voice = voice;
}
public void speak() {
System.out.println(this.voice);
}
}
class Dog extends Animal {
public Dog() {
setVoice("woof");
}
}
You can use a method to access the member and override it in subclasses.
Class A{
public void DoStuff(){
int aux = getResource;
/*cool things with aux*/
}
protected int getResource(){
return internal_member;
}
private int internal_member;
}
Class B extends A{
private int another_member;
#Override
public int getResource(){
return another_member;
}
}
But take into account that this will not prevent people chaging class A from using the member directly, It might be better to create a base class for the members and the getters.
Another Option, as some people outlined before is to have the data member in the base class as protected and initialize it in the subclass:
Class A{
public void DoStuff(){
/*cool things with internal_member*/
}
protected List internal_member;
A(){internal_member = /*Set here a value*/}
}
Class B extends A{
B(){internal_member = /*Set a different value here! you can even declare a member and assign it here*/}
}
You can use constructors with arguments if you need.
I have a abstract class where I want to declare final variables.
However, I want to assign the values to these variables only in the constructors of my sub-classes.
Apparently, this is not possible because all "final fields have to be initialized". I do not see why, since it is not possible anyway to instantiate an abstract class.
What I would like to have is something like this:
abstract class BaseClass {
protected final int a;
}
class SubClass extends BaseClass {
public SubClass() {
a = 6;
}
}
I imagine something similar to methods when you implement an interface. Then you are also forced to to implement the methods in the (sub-)class.
You should define a constructor in your abstract class that takes a value for a and call this constructor from your sub classes. This way, you would ensure that your final attribute is always initialized.
abstract class BaseClass {
protected final int a;
protected BaseClass(int a)
{
this.a = a;
}
}
class SubClass extends BaseClass {
public SubClass() {
super(6);
}
}
I have the following situation:
public abstract class A {
private Object superMember;
public A() {
superMember = initializeSuperMember();
// some additional checks and stuff based on the initialization of superMember (***)
}
protected abstract Object initializeSuperMember();
}
class B extends A {
private Object subMember;
public B(Object subMember) {
super();
subMember = subMember;
}
protected Object initializeSuperMember() {
// doesn't matter what method is called on subMember, just that there is an access on it
return subMember.get(); // => NPE
}
}
The problem is that I get a NPE on a new object B creation.
I know I can avoid this by calling an initializeSuperMember() after I assign the subMember content in the subclass constructor but it would mean I have to do this for each of the subclasses(marked * in the code).
And since I have to call super() as the first thing in the subclass constructor I can't initialize subMember before the call to super().
Anyone care to tell me if there's a better way to do this or if I am trying to do something alltogether wrong?
Two problems:
First, you should never call an overrideable member function from a constructor, for just the reason you discovered. See this thread for a nice discussion of the issue, including alternative approaches.
Second, in the constructor for B, you need:
this.subMember = subMember;
The constructor parameter name masks the field name, so you need this. to refer to the field.
Follow the chain of invocation:
You invoke the B() constructor.
It invokes the A() constructor.
The A() constructor invokes the overridden abstract methot
The method B#initializeSuperMember() references subMember, which has not yet been initialized. NPE.
It is never valid to do what you have done.
Also, it is not clear what you are trying to accomplish. You should ask a separate question explaining what your goal is.
Hum, this code does not look good and in all likelyhood this is a sign of a bad situation. But there are some tricks that can help you do what you want, using a factory method like this:
public static abstract class A {
public abstract Object createObject();
}
public static abstract class B extends A {
private Object member;
public B(Object member) {
super();
this.member = member;
}
}
public static B createB(final Object member) {
return new B(member) {
#Override
public Object createObject() {
return member.getClass();
}
};
}
The problem is when you call super(), the subMember is not initialized yet. You need to pass subMemeber as a parameter.
public abstract class A {
public A (Object subMember) {
// initialize here
}
}
class B extends A {
public B (Object subMember) {
super(subMember);
// do your other things
}
}
Since you don't want to have subMember in the abstract class, another approach is to override the getter.
public abstract class A {
public abstract Object getSuperMember();
protected void checkSuperMember() {
// check if the supberMember is fine
}
}
public class B extends A {
private Object subMember;
public B(Object subMember) {
super();
this.subMember = subMember;
checkSuperMemeber();
}
#Override
public Object getSuperMember() {
return subMember.get();
}
}
I hope this can remove your duplicate code as well.