Java 扩展对象并继承所有变量

Java 扩展对象并继承所有变量,java,inheritance,Java,Inheritance,假设我有一个汽车类的对象,有30个变量,从最高速度到颜色。我想制作一个MyCar对象(类MyCar扩展了Car),它基本上是一样的,只是它存储了更多的信息 我不可能立即创建MyCar对象(因为在数千个汽车对象中,只有少数会成为MyCar对象),除非我将其他字段留空,但这似乎不太专业。而且,创建一个接受30个参数的构造函数,或者通过方法调用设置30个参数,也是如此 那么,有没有任何方法可以轻松地从超类对象继承所有变量 PS:我的课程不是关于汽车的,但我想这会是一个更简单的例子 编辑 谢谢你的回复。

假设我有一个汽车类的对象,有30个变量,从最高速度到颜色。我想制作一个MyCar对象(类MyCar扩展了Car),它基本上是一样的,只是它存储了更多的信息

我不可能立即创建MyCar对象(因为在数千个汽车对象中,只有少数会成为MyCar对象),除非我将其他字段留空,但这似乎不太专业。而且,创建一个接受30个参数的构造函数,或者通过方法调用设置30个参数,也是如此

那么,有没有任何方法可以轻松地从超类对象继承所有变量

PS:我的课程不是关于汽车的,但我想这会是一个更简单的例子

编辑

谢谢你的回复。它们对我的程序都有帮助,但对这个特殊问题没有帮助。建设者似乎没有什么好处,因为我的这些车没有默认的变量值。每次制造汽车时,都会填写所有变量(这是构建一种“事实表”所需的)

信封是一个有趣的设计,但仍然需要复制子类构造函数中的所有变量。我希望有一种方法可以避免这种情况。模板还要求我逐个复制所有变量

在我的程序中,子类在搜索引擎中充当一种“包装类”。这些子类与普通汽车相同,但它们有一个“排名分数”。我的程序设计用于显示普通汽车,通过扩展这些程序,我可以轻松地显示子类,同时按分数排序

无论如何,我必须创建新对象,因为可以在同一个汽车列表上执行多个搜索。因此,在原始车辆中编辑变量不是一个选项

也许有更好的方法解决这个问题,但现在我想我必须将超类对象传递到构造函数中,并将所有变量复制到那里

谢谢你的帮助


PS:我只是在想,也许我可以把所有的变量都放到一个HashMap中。这样,我就可以使用.get(varname)访问它们,并且只需将一个HashMap变量传递到子类中。缺点是我必须进行大量转换,因为变量是字符串、int、double等的混合体。您认为,这是一种可接受的编码方式吗?

您可以添加一个构造函数来获取Car对象,并将值从Car复制到新的MyCar。

有效的Java第二版,项目2:考虑构造函数时遇到许多构造函数参数>/P> 创建一个 构造函数,它接受30个参数, 或者通过方法设置30个参数 电话

如果您面对的构造函数的参数太多,那么您可能需要查看以下内容:。 其思想是只将您想要/知道的字段设置到生成器中,而不必费心处理可选的字段,或希望使用默认值的字段,然后调用
build()
来构造实际对象。请参阅那篇文章中的Java示例

一旦设置了该模式,就可以这样构造汽车(请注意干净的结构):

我不可能立即创建MyCar对象(因为在数千个汽车对象中,只有少数会成为MyCar对象)

所以,你会有很多Car类型的对象,其中一些你想在运行时“升级”为SpecialCar类型

专用汽车和汽车有完全相同的界面吗

您可能需要阅读Coplien的信封字母模式,这是一种在运行时“更改”对象类型的方法。当然,对象并没有真正改变类型;相反,一封不同的“信”进入了现有的“信封”。信封是其他代码引用的句柄,但信封上的方法调用被委托给信件:

 class CarEnvelope { // an envelope
    Car c ; // the letter
    CarEnvelope( Car c ) { this.c = c ; }
    int someMethod() { 
      return c.someMethod(); // delegate 
    }
    void promoteToSpecialType() {
       if( ! c.isSpecialCar() ) {
          c = new SpecialCar( c ) ;
    }
 }

 class Car {
   Car() {}
   int someMethod() { do Car stuff }
   boolean isSpecial() { return false; }
 }

 class SpecialCar extends Car {
   SpecialCar( Car c ) { /*copy c's attributes...*/ } 
   int someMethod() { do SpecialCar stuff}
   boolean isSpecial() { return true; }
 }

 CarEnvelope c = new CarEnvelope( new Car() ) ;
 // do stuff with c
 c.someMethod(); // indirectly calls Car.someMethod();
 // promote
 c.promoteToSpecialType();
 c.someMethod(); // indirectly calls SpecialCar.someMethod

我有一种感觉,你正在寻找的是一个模板的概念;e、 g

public class Car {
   private final int attr1;
   private final int attr2;
   ...

   public Car() {
       super();
   }

   /* copy constructor */
   public Car(Car template) {
       this.attr1 = template.attr1;
       this.attr2 = template.attr2;
       ...
   }

   /* setters and getters */
}
然后

Car myTemplate = new Car();
myTemplate.setAttr1(3);
myTemplate.setAttr2(11);
...

Car car1 = new Car(myTemplate);
car1.setAttr1(4);
Car car2 = new Car(myTemplate);
car1.setAttr1(5);
在这里

我知道这看起来像是懒惰。但是我已经通过在构造函数中手动复制30个变量来实现了。我知道这不是什么大任务

问题是,我被教会了如何用风格来编码。当我看到看起来像复制品的无意识代码块时,我的直觉告诉我可能有更好的方法。因此,我渴望学习和追求完美的愿望驱使我来到这里

但是如果除了复制变量(或者覆盖所有get&set方法)之外真的没有其他方法,那么我就不必再进一步研究了


不用说,这个话题的所有回复都给了我新的见解。谢谢你们。我不明白。常规继承有什么问题

class Car {
    private int attributeOne;
    .....
    private boolean attrbuteThirty;

    public void methodOne(){...}
    ...
    public void methodThirty(){...}
}
然后将其子类化:

 class SubCar extends Car {
     private int extraAttribute;
  }
所有30多个属性和方法都已经被继承,这就是
扩展的全部内容

如果您需要的是基于现有对象的数据创建一个新的对象,但是您拒绝编码它!(,),然后您可以创建一个小脚本来为您创建代码。这很容易。复制/粘贴生成的代码就完成了

如果您不想这样做,因为您不想复制数据,您可以重写有趣的方法,并将代码委托给原始方法,这就是

class SubCar extends Car {
    private Car wrapped;
    private String extraAttribute;
    public SubCar( Car original, String newAttributeOne ) {
        wrapped = original;
        this.extraAttribute = newAttributeOne;
   }

    public void someMethod() {
        wrapped.someMethod();
    }
    public String getName() { return wrapped.getName();  }
    ... and so on
    // new method 
    public String extraAttribute() { return extraAttribute; }
}

这样,您就不会复制数据,而只是对其进行修饰

我们可以创建一个接口ICar,其中包含所有30列的所有getter和setter。 Car可以实现ICar,并且可以包含所有30个字段及其相应的getter和setter。 MyCar还可以实现ICar,并可以使用composition。它将Car的方法公开为委托方法(可以在像eclipse这样的IDE中自动生成)

所有消费者都可以使用ICar inter
class SubCar extends Car {
    private Car wrapped;
    private String extraAttribute;
    public SubCar( Car original, String newAttributeOne ) {
        wrapped = original;
        this.extraAttribute = newAttributeOne;
   }

    public void someMethod() {
        wrapped.someMethod();
    }
    public String getName() { return wrapped.getName();  }
    ... and so on
    // new method 
    public String extraAttribute() { return extraAttribute; }
}
public interface ICar {
// getter and setter methods
}

public Car implements ICar {
 private String color;
 // getters and setters for each of the fields
}

public MyCar implements ICar {
 private Car car;
 public MyCar(Car car){
  this.car = car;
 }
 public String getColor() {
  return car.getColor();
 }
}