Java继承
所以我一直在试图找到一种合适的方法来获得应该非常简单的功能继承(我想要的方式),但我失败得很惨。考虑这一点:Java继承,java,inheritance,Java,Inheritance,所以我一直在试图找到一种合适的方法来获得应该非常简单的功能继承(我想要的方式),但我失败得很惨。考虑这一点: class Parent { public String name = "Parent"; public Parent() {}; public void doStuff() { System.out.println(name); } } class Child extends Parent { public String name = "Child
class Parent
{
public String name = "Parent";
public Parent() {};
public void doStuff()
{
System.out.println(name);
}
}
class Child extends Parent
{
public String name = "Child";
public Child()
{
doStuff();
}
}
我知道Java没有达到我在本例中预期的效果,因为出于某些原因,成员变量没有像方法那样被覆盖,但我的问题是,实现我预期的行为的正确方法是什么?我希望我的基类包含一些对给定子类提供/定义的成员变量进行操作的函数。我认为get/set可以工作,但它破坏了我调用super()并让我的基类进行所需构造的能力,使我的子类包含一系列构造,而不是将其隔离到基类
欢迎提出任何建设性建议。对于单个实例,您真的需要两个不同的name
变量吗?你真的有这样的想法吗?一个对象有“作为父对象时的名称”和“作为子对象时的名称”?如果没有,只需在父类
中使用一个变量即可
父类如何知道子类将提供哪些变量?如果每个子类都有相同的变量集,为什么它们不在父类中
如果你能给出一个更具体的例子来说明你试图解决的问题,那么给出一个具体的答案就更容易了。子类变量
name
正在隐藏同名的超级类变量。因此,当Child
声明并分配name
时,它是另一个单独的变量
取而代之的是,将name作为父继承的属性,并将名称作为参数传递给<代码>父< /代码>构造函数。然后从子构造函数调用
super(“Child”)
class Parent {
protected string name;
public Parent() { name = "parent"};
public doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
name = "child";
doStuff();
}
}
而且,作为公共财产,它应该是最终的。否则,通过getter和setter公开它。如果您想要这种类型的“变量继承”,您总是可以用getter替换变量。不过,不确定“变量继承”((c))总体上是否是一种好的设计模式
class Parent {
public void doStuff() {
System.out.println(getName());
}
public String getName() {
return "Parent";
}
}
class Child extends Parent {
public Child() {
doStuff();
}
public String getName() {
return "Child";
}
}
或者您可以在Parent
类中使用要使用的名称来保护构造函数
编辑我不会称之为“黑客”。将参数传递给父构造函数的版本也可以非常优雅
class Parent {
private final String name;
// don't let use to invoke this constructor, only for child classes
protected Parent(String name) {
this.name = name;
}
// public constructor for users
public Parent() {
this("Parent");
}
public void doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
super("Child");
doStuff();
}
}
你知道为什么Java似乎放弃了继承成员变量的概念吗?java已经放弃了C++的许多概念(从臭名昭著的多重继承开始),因为它们没有给语言增加太多的价值,反而增加了它的复杂性。
虽然我不反对变量继承,但如果没有这个概念,我也不会感到痛苦。就我个人而言,我喜欢简洁明了的语言。你是正确的,因为你不能重写类的成员。您可以通过使
name
受保护并在构造函数中设置它来实现这一点
class Parent {
protected string name;
public Parent() { name = "parent"};
public doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
name = "child";
doStuff();
}
}
您试图做的事情在Java中不起作用。在Java中,父类中声明的属性不会在子类中重写 如果您想要多态行为,那么您需要声明属性private,并在父类中声明相应的getter方法,您可以在子类中重写这些方法 或者:
class Child extends Parent {
public Child() {
name = "Child";
doStuff();
}
}
尽管@shoebox639的答案以更优雅的方式实现了这一点,允许您将属性声明为
final
。(可变公共属性不是一个好主意…您不需要在子类中重新定义成员变量。您可以按照@Stephen C所说的方式编写代码
class Child extends Parent {
public Child() {
name = "Child";
doStuff();
}
}
在你的岗位上
我希望我的基类包含一些对给定子类提供/定义的成员变量进行操作的函数。
您将首先编写您的超类,在这个阶段,您的超类不知道您的子类 乔恩,谢谢你的对话。我不想在父类中声明它们的原因是,每个子类对任何成员都有不同的值。考虑每个子类的不同数组值,其中包含在该数组上运行的一个函数。我不会对父类中的数组声明有任何问题,只是似乎没有一种干净的方法允许子类“重写”(或者说重定义是更好的选择)所说的数组。@user483315:每个子类的每个实例都已经有了不同的值。你的意思是每个变量在每个子类中都是不同的类型吗?不,我没有改变类型,但问题是我希望基类中的函数能够对子类中定义的数组进行操作。似乎公认的做法是在子类构造函数中手动将数据注入基类,由于某种原因,成员变量被完全排除在继承/重写链之外,取而代之的是被接受为这些“影子”变量。拥有一个公共成员变量并不是一个好主意。这是一个可怕的问题,它甚至没有说输出是什么-这就像要求某人不仅调试你的问题,甚至不显示你当前得到的…同意,如果你想要一个可重写的字段,只需使用getterPlease查看我对Stephen C的答复,我理解让它工作的黑客手段,我只是希望有人能想出一个比手动将数据打包回基类更优雅的解决方案。接下来,您知道为什么Java似乎放弃了继承成员变量的概念吗?这对我来说似乎是错误的,但我知道什么:P.让我感到奇怪的是,忽略它实际上会导致不美观,特别是在这种情况下,因为我想使用基类构造函数在我的子类之间实际构造一些常见的东西,但我不能,因为我必须“设置”基类