2

Here, it says that:

This gives MountainBike all the same fields and methods as Bicycle, yet allows its code to focus exclusively on the features that make it unique. This makes code for your subclasses easy to read. However, you must take care to properly document the state and behavior that each superclass defines, since that code will not appear in the source file of each subclass.

However in my code the inheritance doesn't work properly, probably due to a flaw in my code?

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();

    }

}

The mountainbike class should inherit all the characteristics of the bicycle class, right? I added a unique property which is int speed = 10, so starting speed should be 10. However on running the compiler treats starting speed as 0.

Any ideas?

1
  • Thanks for the responses. Apparently there are multiple ways of getting around an obstacle in the world of programming :D For now I guess I'll use constructors and assign speed = 10 for simplicity's sake, I don't really know how to use the public and private and the super() stuff. Commented Dec 18, 2009 at 12:28

8 Answers 8

6

No, your Mountainbike class should not redefine a speed variable. You need to pass the initial speed (10) to the constructor of its super class using super as part of the constructor call:

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);
  }
}

I would recommend against using protected variables for speed and gear. It is good practice to enforce encapsulation by declaring the speed and gear variables private in the base class.


EDIT:

Apparently, you're beginning with Java programming. I suggest you have a look at this free online book written by Bruce Eckel: Thinking in Java.

Sign up to request clarification or add additional context in comments.

1 Comment

could the downvoter point the problem so that I can correct it please?
5
public class Bicycle {
   private int speed;

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


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

3 Comments

What's the 2nd public Bicycle (int speed) { (line 4) for?
and for the explanation on access modifiers, it's just 2 pages away: java.sun.com/docs/books/tutorial/java/javaOO/variables.html
4

You cannot override fields, only methods. What you have to do is mark the speed field as protected, add a constructor to your subclass and set the field's value in that constructor, like this:

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

BTW, note that I have corrected your class names: Java has an overwhelmingly strong convention for uppercase class names; using lowercase class names will only confuse people who look at your code.

5 Comments

I would recommend against using protected variables. A private int speed variable enforces encapsulation better.
How do you mark it as protected? I get the idea about setting the field (which means variable, right?)'s value in the constructor, but I don't see how you protect the field.
@Fabian: you just write protected int speed; when declaring the variable. See codeguru.com/java/tij/tij0020.shtml#Index45
Just write "protected" in front of the field name (field is a non-local variable). It means that the field is accessible directly by code in subclasses even if they're not in the same package - so it's probably not necessary for your code and will probably be introduced later in your course. but Gregory is right - r3zn1k's solution is cleaner.
or mine :p anyway, welcome to Java, we hope you enjoy the flight
3

You've introduced a new speed variable in mountainbike which hides the one in bicycle. This is a bad idea - having two variables with the same name at different levels of the type hierarchy will cause confusion, particularly when they're both accessible.

Instead, you want to change the value of the existing variable to 10. For example:

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

IMO the field should really be private in the base class, accessed via a property instead - and as others have posted, having a constructor in the base class which accepts the initial speed would also be a good idea.

Comments

1

In fact you are redeclaring the field speed in your class mountainbike.

for example you can init the speed in the constructor of the class mountainbike.

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

Comments

1

In Java, there's a concept of scopes. What's happening is that the speed variable isn't actually getting overriden, therefore it still defaults to 0.

Comments

1

You can't override a field, only methods.

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

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

Comments

0

You are hiding away bicycle.speed with mountainbike.speed so basically each mountainbike instance has two int member variables for speed, one will be this.speed and the other this.super.speed.

Instead of redeclaring int speed inside mountainbike you should just create a default constructor for mountainbike and set this.speed = xxx; in there.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.