开发者

Overwrite variable or force usage?

开发者 https://www.devze.com 2022-12-08 10:41 出处:网络
I want to force a class to define a certain variable from the class it implements. e.g. class Fruit{ String name; // Cause each fruit has a name

I want to force a class to define a certain variable from the class it implements. e.g.

class Fruit{
     String name; // Cause each fruit has a name
}

//Apple wants to get an error if it does not use the name variable
class Apple implemen开发者_高级运维ts Fruit {
     String name = "Apple";
}

Is there a way to do that? Just like java.io.Serializable does it?


The easiest way, I suppose, is using the constructor.

class Fruit{
     private final String name; 
     public Fruit(String name){ 
         if (/* name has an incorrect value, is null or whatever */) 
             throw new IllegalArgumentException("name");
         this.name = name; 
     }
}

//Apple wants to get an error if it does not use the name variable
class Apple extends Fruit {
     public Apple(){ super("Apple"); }
}

Now it's impossible to make a Fruit subclass which doesn't pass a name to the Fruit constructor. By making the field final, you also get the added bonus that once the field has been set to a proper value, subclasses can't put bogus stuff there (except for using reflection etc, but then all bets are off).

Edit: Also, as pointed out by more attentive posters, you don't implement classes, you extend them. For interfaces (which you do implement), you can't enforce that sane values are returned from the methods (not in any easy way - I suppose you could use AOP to check the return values and throw an IllegalStateException when bogus values are returned).


You can't override variables in Java. Just use a interface with setter/getters or the constructor variant from gustafc. Here's an quick'n'dirty example:

interface Fruit {
  String getName();
  void setName(String name);
}

class Apple implements Fruit {
  private String myName="";

  public void setName(String name) { myName=name;}
  public String getName() { return myName;}
}

I personally favor the constructor variant, so things wont get null.


The first call in subclass constructor, is a call to superclass constructor (required, added by compiler if needed). So, when the desired value has to be calculated in subclass constructor, the "constructor strategie" is not possible. In such case the strategie below can be used:

Declare an abstracct method in superclass, returning the desired value, for example:

protected abstract String getValue();

In superclass, everywhere you need the value, use the getValue() method.

In subclass store the value as private field, for example:

private String value;

In subclass initialize/set the value (for example in constructor) and implement the abstract method (required, class does not compile otherwise):

@Override
protected String getValue() {
   return value;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号