我有一个名为Car的抽象类。然后我有两个子类,福特和道奇,它们都扩展了Car。这些子类中的每一个都有一个名为move()的方法。这个方法中的代码对于Ford和Dodge来说是相同的,所以我的本能就是把这个方法实现抛给Car超类,所以我不必在我的两个子类中都有两次相同的代码,即得到重复的代码,只是将此方法在超类内的代码中写出一次,每个子类可以在需要时调用它。
现在这是我的......事情:在每个子类的移动方法中,每个子类的实例变量都被操纵。所以你看,即使代码是相同的,每个move()中发生的事情 - 方法取决于特定子类的实例变量的状态。像这样:
abstract class Car {
// I want to put move()-method in here and erase it from subclasses
}
class Ford extends Car {
private int rpm;
public void move(){
dosomestuff + rpm // value of rpm being used here is unique to Ford
}
}
class Dodge extends Car {
private int rpm;
public void move(){
dosomestuff + rpm // value of rpm being used here is unique to Dodge
}
}
我希望这样,并使用子类实例变量从每个子类的超类中调用move():
abstract class Car {
move(){
// do stuff that is identical to Ford and Dodge but
// dependent on different instance variables
}
}
class Ford extends Car {
private int rpm;
}
class Dodge extends Car {
private int rpm;
}
我应该在超类Car中创建变量吗?但这就是我遇到问题,因为我知道抽象类无法实例化!所以如果我在这种情况下传递rpm变量作为move()方法中的参数,如move(rpm),而我只在Car类中实现move(),我将不得不返回rpm-variable以获取其操纵值。这适用于一次实例变量形式的子类。问题是,移动方法取决于几种不同的变量。所以我每次都要将几个变量返回子类,但我不知道该怎么做。
我很困惑。如何将我的子类中的“重复代码”压缩到超类Car中,并且仍能够从继承自Car类的不同子类中操作实例变量?我是否将它们作为参数传递并返回?我是否使用get-set方法做某事?我很不确定......
答案 0 :(得分:7)
使用protected
变量
abstract class Car {
protected int rpm;
move(){
// ACCESS RPM HERE, which would be specific to implementing class
}
}
class Ford extends Car {
}
class Dodge extends Car {
}
由于变量rpm
现在受到保护,Car
的子类可以访问它,当您实例化Ford
或Dodge
时,它会拥有它拥有rpm
值。
有道理吗?
答案 1 :(得分:1)
我不知道这是否能回答你的问题,但是子类继承了超类的方法,所以我会将所有内容都放在抽象类中,并使用getter setter(或access-mutate)方法来使用抽象类中的所有变量。我注意到有人声明了保护变量,这些变量有时会起作用,但如果你需要封装在你的包中,则不会我会这样做:
public abstract class Car{
private int rpm;
public int getRPM(){return rpm;}
public void move(){//do move using getRPM() to access the data}
}
class Ford extends Car {
}
class Dodge extends Car {
}
那么福特和Doge之间唯一不同的是构造函数,当你进行子类化时,这通常是好的
答案 2 :(得分:0)
正如其他人所写,您可以将实例变量拉入基类;使它们受到保护;或为他们提供吸气剂;但说实话,我认为最有可能导致糟糕设计。
事情是:继承应该用于为其子类提供行为,而不是变量。
意义:你仔细考虑你想要“分享”的行为;然后你考虑open closed principle以正确的方式实现它,如:
abstract class Base {
public final void doTheCommonThing() {
System.out.println("but we need subclass stuff: " + getFromSubclass());
}
protected abstract String getFromSubclass();
}
数据封装的重点是你的基类不应该知道关于子类中的变量;反之亦然。因为这些是实施细节,没有其他人有业务知道。