开发者

Java Inheritance... Confused

I have a abstract Parent class that has multiple children. I'd like the child to be able to have a variable that is the same for every instance of that child. I'd prefer not to pass a constructor to the child to tell it it's name because that just seems silly when it can be hardcoded. From what I've read doing the following "hides" the parents instance variable and doesn't work as I want.

public abstract class Parent {
    public String name = "the parent";
   开发者_运维技巧 public getName(name);
}
public class Child1 extends Parent {
    public String name = "Jon";
}
public class Child2 extends Parent {
    public String name = "Mary";
}

Child1 c = new Child1();
c.getName(); // want this to return "Jon", but instead returns "the parent".

To be clear, basically what I want is something like c.getClass().getName() but I don't want to have the result of that dependent on the Class name, but rather on a hardcoded value.

Thanks


You could declare an abstract method in the parent and have each child implement the method to return the appropriate name, like this:

public abstract class Parent {
    public abstract String getName();
}

public class Child1 extends Parent {
    private static final String NAME = "Jon";
    public String getName() { return NAME; }
}

public class Child2 extends Parent {
    private static final String NAME = "Mary";
    public String getName() { return NAME; }
}


Depending on what you're actually trying for, there are a couple of solutions. One is to make the child classes provide the name to the parent:

public abstract class Parent {
    protected Parent(String name) {
        this.name = name;
    }
    public getName() {return name;}
}
public class Child1 extends Parent {
    public Child1() {
        super("Jon");
    }

}
public class Child2 extends Parent {
    public Child2() {
        super("Mary");
    }
}

Another is to use method inheritance like Isaac Truett suggests.


Create a static final String in each child that has your hard-coded name:

public class Child1 extends Parent 
{
    public static final String NAME = "Jon";
}


Use a method instead of a field (variable):

public abstract class Parent {
  public String getName() {
    return "the parent";
  }
}

public class Child1 extends Parent {
  public String getName() {
    return "Jon";
  }
}
public class Child2 extends Parent {
  public String getName() {
    return "Mary";
  }
}

In Java, at least, you can only override methods, not variables.

Another option would be to have Parent's constructor take the name as a parameter. If you do this it's best if Parent is abstract and all of the constructors take the name parameter. Then subclasses are required to pass in the name, which would typically be done something like this:

public class Child1 extends Parent {
  public Child1() {
    this("Jon");
    // ...
  }
}

Actually, even with the method overriding approach, it's nice if Parent is abstract so you can make getName() abstract.


The reason why your call to getName() doesn't return the child's name is because you've created a new variable call name within the child. Try this:

public class Child3 extends Parent{
    public String name = "Jon";

    public String getNames(){
        return super.name + " : " + name;
    }
}

You will see:

the parent : Jon

The correct way to set the name of the child into the parent's name variable is to say:

super.name = "Jon";


You need to overwrite the getName function in order to get the result you want. Because the new String name is not replacing the parent name so the getName function is actually reading the parent String


Why not use the constructors?

public abstract class Parent {
    public String name = "the parent";
    public String getName() {
      return name;
    }
    public void setName(String s){
      name = s;
    }
}
public class Child1 extends Parent {
    public Child1() {
      setName("Jon");
    }
}
public class Child2 extends Parent {
    public Child2() {
      setName("Mary");
    }
}

Child1 c = new Child1();
c.getName(); 

// Prints 'Jon'


You could do this using Java Reflection... but it's not a very clean way of doing things:

public abstract class Parent {
    public String name = "the parent";
    public String getName() throws Exception { return getClass().getField("name").get(this).toString(); }
}

Although I think Isaac's approach is the best way to approach the solution.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜