Java: static field in abstract class

后端 未结 8 1064
独厮守ぢ
独厮守ぢ 2020-12-24 01:04

I just start out with an example, that explains it best:

public abstract class A{
    static String str;
}

public class B extends A{
    public B(){
                


        
相关标签:
8条回答
  • 2020-12-24 01:17

    Since you hardcode the value or str in subclasses anyway, you can do something like this:

    public abstract class A{
        public abstract String getStr();
    }
    
    public class B extends A{
       public String getStr(){
          return "123";
       }
    }
    
    public class C extends A{
       public String getStr(){
          return "abc";
       }
    }
    

    This would do the trick in your case.

    Of course, then you should call it by method, like this:

    public class Main{
    
        public static void main(String[] args){
            A b = new B();
            A c = new C();
            System.out.println("b.str = " + b.getStr());
            System.out.println("c.str = " + c.getStr());
        }
    }
    
    0 讨论(0)
  • 2020-12-24 01:23

    This will print the output you want:

    public abstract class A{
    }
    
    public class B extends A{
        static String str;
    
        public B(){
            str = "123";
        }
    }
    
    public class C extends A{
        static String str;
    
        public C(){
            str = "abc";
        }
    }
    
    public class Main{
    
        public static void main(String[] args){
            A a = new B();
            A c = new C();
            System.out.println("B.str = " + B.str);
            System.out.println("C.str = " + C.str);
        }
    }
    
    0 讨论(0)
  • 2020-12-24 01:24

    If you want classes B and C to have separate static variables, you'll need to declare the variables in those classes. Basically, static members and polymorphism don't go together.

    Note that accessing static members through references is a really bad idea in terms of readability - it makes it look like it depends on the value of the reference, when it doesn't really. So your current code won't even compile when you've moved str down to B and C. Instead, you'll need

    System.out.println("b.str = " + B.str);
    System.out.println("c.str = " + C.str);
    

    If you really need to access the value polymorphically (i.e. through an instance of A) then one option is to make a polymorphic getter:

    public class A {
        public abstract String getStr();
    }
    
    public class B extends A {
        private static String str = "b";
    
        @Override public String getStr() {
            return str;
        }
    }
    

    (and the same for C).

    That way you get the behaviour you want in terms of not having a separate variable per instance, but you can still use it polymorphically. It's a little odd for an instance member to return a static value like this, but you're using the value for polymorphism of type, basically...

    0 讨论(0)
  • 2020-12-24 01:24

    I think one way to approach this is to use a singleton for class B and C to mimic static methods and fields. The can both extend abstract class A, but will have their own values of str..

    0 讨论(0)
  • 2020-12-24 01:27

    Put the static varibale in each subclass and add a (not static) abstract method to the abstract superclass:

    abstract String getStr();
    

    Then implement the getStr() method in each subclass by returning the static field of this special subclass.

    public class B extends A {
     private static String str;
    
      @Override
      public String getStr() {
        return B.str;
      }
    }
    
    0 讨论(0)
  • 2020-12-24 01:32
    public abstract class A {
        private String str;
        public String getStr() { return str;}
        protected void setStr(String str) { this.str = str; }
    }
    

    Then you'll be able to have

    B b = new B();
    b.getStr();
    

    The setter and getter are my addition, you can go by simply making the variable non-static.

    Update If you want to have the static-per-subclass, then you can have:

    protected static Map<Class, String> values;
    public abstract String getValue();
    

    and then:

    public String getValue() {
        values.get(getClass());
    }
    public void setValue(String value) {
        values.set(getClass(), value);
    }
    

    But this is generally a bad idea.

    0 讨论(0)
提交回复
热议问题