2015-11-14 78 views
0

如何访问其父类中声明的子类的字符串变量?如何从父母的方法访问孩子的继承成员

我上课的类似:

public class Parent { 
    public void display() { 
    // displays A 
    } 
} 

public class Child1 extends Parent { 
} 

public class Child2 extends Parent { 
} 

Parent p1 = new Child1(); 
Parent p2 = new Child2(); 

p1.display(); // Currently displaying parent value of A 
p2.display(); // Currently displaying parent value of A 

如何保证这里面display(),既p1p2使用自己的值A,而不是父类?因为你不使用静态成员

期望的行为是正常行为,所以长;

+2

如果'Parent'类不是抽象的,使其具有参数的构造'(字符串一)'。然后从子类调用'super(A)' –

+3

你能重写你的问题吗,因为我不明白你的意思是什么 –

+0

我试过编辑这个问题。对不起,这是一个完整的重写,但原来很难理解。如果我的棍棒结尾错误,请将编辑拖回(或更新我的编辑)。 –

回答

0

(道歉,如果我误解了这个问题,我回答这个问题,因为我已经编辑它。) 。在超类中定义所需的成员为protected;这三个类中的任何一个的每个实例都将使用它自己的值。

public class Parent { 
    protected string name; 

    public Parent() { 
    name = "Parent's value"; 
    } 

    public void setName(string newValue) { 
    name = newValue; 
    } 

    public void display() { 
    System.out.println(name); 
    } 
} 

public class Child1 extends Parent { 
    public Child1() { 
    name = "Child1's value"; 
    } 
} 

public class Child2 extends Parent { 
    public Child2() { 
    name = "Child2's value"; 
    } 
} 

public static void main() { 
    new Parent().display(); 
    new Child1().display(); 
    Child2 c2 = new Child2(); 
    c2.display(); 
    c2.setName("New name!"); 
    c2.display(); 
} 

这产生了预期的输出:

Parent's value 
Child1's value 
Child2's value 
New name! 
+0

如果变量构造的一部分,它会强制子类时,他们实例始终使用一个不同的变量;你认为这种限制的灵活性;我想知道你对在父项中使用getName()方法的意见,并覆盖它,如上面在我的回复中所述。 – smc

+0

在父项中使用'getName()'就好了。但是,对'name'成员进行多次声明或对'getName()'方法进行多个定义是没有意义的。它们都可以在Parent中完成。这个子类不需要任何特殊的代码。 –

+0

“如果变量构造的一部分,它会强制子类时,他们实例始终使用一个不同的变量”。这是不正确的,它不强制执行任何操作。你可能有一个'setName()'方法或者直接简单地使用这个属性。在我的示例代码中,'Child1'和'Child2'直接更新'name'属性。你不需要一个不同的变量。 –

0

替代地,如果有是得到A的值,像getA()class Parent,覆盖的方法在每个class Child1class Child2的返回的方法他们各自的A值。

我通过@保罗 - 希克斯重用例子,演示-ED我下面的方法:

public class Parent 
    ... 
    public void display() { 
     System.out.println(getA()); 
    } 

    protected String getName() { 
     return "parent"; 
    } 
} 

class Child1 { 
    ... 
    protected String getName() { 
     return "child1"; 
    } 
} 

class Child2 { 
    ... 
    protected String getName() { 
     return "child2"; 
    } 
} 
+0

此版本不使用任何字段/成员,只是常量。这非常不灵活。如果'getName()'实际上会返回'name'成员,那么它和我的答案一样。我只是为了示例的目的而使用了一个快捷方式:我使用了受保护的成员而不是访问者。相识又有差别。 –

+0

@PaulHicks当你指出我的版本不使用字段/成员时,我意识到我离题了。你已经写了一个示例代码来问问这个问题的人的利益,并且我对这个问题的设计方面进行了分析。是的,它是一样的。 – smc

1

有做这一个很常见的方式。这是一个java'模式'。这种技术是在面向对象设计中使用getter/setter方法的一个驱动示例。

声明父级中值A的抽象getter/setter方法在子类中完全定义它们。父母通常使用getter/setter来访问该值。

通过这种方式,父级和子级将始终使用'A'值作为子类中的声明,管理和更新。吸气剂和吸附剂不能是静态的(当然,这是没有意义的)。此方法允许父级和子级保持独立,并且可以以非常灵活和干净的方式修改/调整孩子。特别是,子类不需要主动维护A,并且可以通过JIT(即时)方式计算,重复检查或委托A的请求。

完整的例子:

public abstract class Parent { 
    // These two methods must be overridden by all child classes. Compiler enforces that. 
    public abstract int getA(); 
    public abstract int setA(int newA); 
     // This display routine utilizes the *childs* a 
    public void display() { someoutput.write(this.getA()); } 
} 

public class Child1 extends Parent { 
    SomeFancyOrPartularFormOfA a = null; // a Jazzy type of A, used by parent. 
    @Override // Let java and IDEs know we intend to override it. 
    public int getA() { return(this.a.gatherorcalcA()); } 
    @Override // Let java and IDEs know we intend to override it. 
    public int setA(int newA) { this.a.setorincorporateA(newA); } 
    . . . 
} 
public class Child2 extends Parent { 
    Integer a = 0; // A more mundane type of A, still used by parent. 
    @Override // Let java and IDEs know we intend to override it. 
    public int getA() { return(this.a); } 
    @Override // Let java and IDEs know we intend to override it. 
    public int setA(int newA) { this.a = newA; } 
    . . . 
} 
+0

好莱坞原理/模板方法模式? – smc

+0

是的,这是一个缩小的模板方法,4个“设计模式”团伙。在这个更简单的变体中,子类重新定义数据的存储和管理而不是算法本身。 – TSnyder