Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workaround for abstract attributes in Java

In Scala I would write an abstract class with an abstract attribute path:

abstract class Base {

    val path: String

}

class Sub extends Base {

    override val path = "/demo/"

}

Java doesn't know abstract attributes and I wonder what would be the best way to work around this limitation.

My ideas:

a) constructor parameter

abstract class Base {

  protected String path;

  protected Base(String path) {
    this.path = path;
  }

}

class Sub extends Base {

    public Sub() {
        super("/demo/");
    }

}

b) abstract method

abstract class Base { // could be an interface too

  abstract String getPath();

}

class Sub extends Base {

    public String getPath() {
        return "/demo/";
    }

}

Which one do you like better? Other ideas?

I tend to use the constructor since the path value should not be computed at runtime.

like image 495
deamon Avatar asked May 12 '10 14:05

deamon


People also ask

Can we override the abstract method in Java?

A subclass must override all abstract methods of an abstract class. However, if the subclass is declared abstract, it's not mandatory to override abstract methods.

Can you have abstract attributes Java?

Java doesn't support abstract properties, if you try to mark a class property as abstract, you get a compilation error. In this tutorial, we introduce 2 ways for defining abstract properties which are set by subclasses without using the abstract keyword.

How do you override an abstract?

A non-abstract child class of an abstract parent class must override each of the abstract methods of its parent. A non-abstract child must override each abstract method inherited from its parent by defining a method with the same signature and same return type. Objects of the child class will include this method.

Can we override non-abstract method of abstract class in Java?

An abstract class can have a mixture of abstract and non-abstract methods. Subclasses of an abstract class must implement (override) all abstract methods of its abstract superclass. The non-abstract methods of the superclass are just inherited as they are. They can also be overridden, if needed.


3 Answers

What Scala does internally is what you are describing as method B.

Take the following example class:

abstract class Test{
    val path: String
}

When you compile this with scalac, it will generate an abstract Java class with an abstract method named attr that returns a String. The reason this can happen is, because a val is constant and as such it can be emulated by only a getter and no setter. So if you want to access this class from Java, you can simply override the abstract getter method.

This is the equivalent of the Java class that will be produced (output of javap):

public abstract class Test extends java.lang.Object implements scala.ScalaObject{
    public abstract java.lang.String path();
    public Test();
}
like image 103
ziggystar Avatar answered Oct 26 '22 23:10

ziggystar


If the path never changes, I would go for option a, otherwise I would go for option b.

Another aspect is that the value of path may not be available at the time of the construction. In that case option a is sort of ruled out. Comparing to your Scala code however, it seems like path is available at the time of the construction.

like image 25
aioobe Avatar answered Oct 27 '22 00:10

aioobe


The equivalent is B since the values is fixed.

Option A receives the path in the constructor, and that value could be computed during runtime which is not what the Sub class in the scala example is goind.

like image 42
OscarRyz Avatar answered Oct 26 '22 23:10

OscarRyz