2009-12-18 164 views
2

Here,它说:Java类继承

这给山地车所有相同的字段和方法自行车,但允许其代码完全集中于,使其独特的功能。这使得您的子类的代码易于阅读。但是,必须注意正确记录每个超类定义的状态和行为,因为该代码不会出现在每个子类的源文件中。

但是在我的代码中,继承无法正常工作,可能是由于我的代码存在缺陷?

package java1; 

class bicycle { 
    int speed = 0; 
    int gear = 1; 

    void accelerate(int incr) { 
     speed = speed + incr; 
    } 

    void decelerate(int incr) { 
     speed = speed - incr; 
    } 

    void changeGear(int val) { 
     gear = val; 
    } 

    void printInfo() { 
     System.out.println("Speed: " + speed + " Gear: " + gear); 
    } 
} 

class mountainbike extends bicycle { 
    int speed = 10; 
} 

public class Main { 

    public static void main(String[] args) { 

     mountainbike mb1 = new mountainbike(); 

     mb1.accelerate(20); 
     mb1.accelerate(10); 

     mb1.printInfo(); 

    } 

} 

山地自行车班应该继承自行车班的所有特点吧?我添加了一个独特的属性,它是int speed = 10,所以启动速度应该是10。不过上运行的编译器将启动速度为0

任何想法?

+0

感谢您的回复。显然,在编程世界中有很多种方法来解决障碍:D 现在我想我会使用构造函数并为简单起见分配'speed = 10',我真的不知道如何使用' public'和'private'和'super()'的东西。 – Fabian 2009-12-18 12:28:07

回答

6

不,你的Mountainbike类不应该重新定义speed变量。你需要的初始速度(10)传递给使用super其超类的构造函数的构造函数调用的一部分:

package java1; 

class Bicycle 
{ 

    Bicycle(int speed, int gear) 
    { 
    this.speed = speed; 
    this.gear = gear; 
    } 

    public void accelerate(int incr) 
    { 
    speed = speed + incr; 
    } 

    public void decelerate(int incr) 
    { 
    speed = speed - incr; 
    } 

    void changeGear(int val) 
    { 
    gear = val; 
    } 

    public String toString() 
    { 
    return "Speed: " + speed + " Gear: " + gear; 
    } 

    private int speed = 0; 
    private int gear = 1; 

} 

class Mountainbike extends Bicycle 
{ 
    public Mountainbike() 
    { 
    super(10, 1); 
    } 
} 

public class Main { 

    public static void main(String[] args) 
    {  
    Mountainbike mb1 = new Mountainbike(); 

    mb1.accelerate(20); 
    mb1.accelerate(10); 

    System.out.println(mb1); 
    } 
} 

我会建议不要使用速度和档位protected变量。它是通过在基类中声明speedgear变量private执行封装好的做法。


编辑:

显然,你用Java编程开始。我建议你看看这本由Bruce Eckel编写的免费在线书:Thinking in Java

+2

可以downvoter指出问题,以便我可以纠正它吗? – 2009-12-18 10:58:35

1

事实上你重新声明场速度类山地。

例如,你可以初始化速度在类山地自行车的构造。

class mountainbike extends bicycle { 
mountainbike() { 
    speed=10; 
} 
} 
3

你介绍一个mountainbikespeed变量,它隐藏了一个在bicycle。这是一个坏主意 - 在类型层次结构的不同级别使用两个具有相同名称的变量会造成混淆,特别是当它们都可访问时。

相反,要在现有变量的值更改为10。例如:

class mountainbike extends bicycle { 
    mountainbike() { 
     speed = 10; 
    } 
} 

IMO领域确实应该在基类中,通过属性访问,而不是私人 - 和正如其他人所发布的那样,在接受初始速度的基类中有一个构造函数也是一个好主意。

5
public class Bicycle { 
    private int speed; 

    public Bicycle (int speed) { 
     this.speed = speed; 
    } 
} 


public class Mountainbike extends Bicycle { 
    public Mountainbike() { 
     super(10); 
    } 
} 
+1

-1缺少解释。 – Bombe 2009-12-18 10:56:28

+3

@Bombe,认真...... – 2009-12-18 11:05:31

+0

第二个'公共自行车(int speed){'(line 4)是什么? – Fabian 2009-12-18 11:05:39

4

您不能覆盖字段,只能使用方法。你要做的是什么标记speed场为protected,构造函数添加到您的子类,并在构造函数中设置字段的值,就像这样:

class Mountainbike extends Bicycle { 
    public Mountainbike() 
    { 
     speed = 10; 
    } 
} 

顺便说一句,请注意,我已经纠正你的类名:Java的对大写的类名称具有压倒性的强大惯例;使用小写的类名只会混淆查看代码的人。

+0

我建议不要使用'protected'变量。一个'私人int速度'变量强制封装更好。 – 2009-12-18 11:00:55

+1

你如何将其标记为受保护的?我知道在构造函数中设置字段(这意味着变量,对吗?)的价值,但我不明白你是如何保护字段的。 – Fabian 2009-12-18 11:06:49

+0

@Fabian:在声明变量时,你只需写'protected int speed;'。请参阅http://www.codeguru.com/java/tij/tij0020.shtml#Index45 – 2009-12-18 11:10:39

1

在Java中,有一个概念scopes。什么情况是,变速实际上没有得到重写,因此它仍然默认为0。

0

你躲着走bicycle.speedmountainbike.speed所以基本上每个山地实例具有速度两个int成员变量,一会this.speed和其他this.super.speed

而不是在山地自行车内重新声明int速度,你应该创建一个山地自行车的默认构造函数,并在那里设置this.speed = xxx;

1

你不能覆盖一个字段,只能是方法。

class bicycle { 
    int getSpeed() { 
     return 0; 
    } 
    // ... other things 
} 

class mountainbike extends bicycle { 
    int getSpeed() { 
     return 10; 
    } 
    // ... other things 
}