Наследование классов Java - PullRequest
2 голосов
/ 18 декабря 2009

Здесь , это говорит о том, что:

Это дает MountainBike все те же поля и методы, что и Bicycle, но позволяет его коду сосредоточиться исключительно на функциях, которые делают его уникальным. Это делает код для ваших подклассов легко читаемым. Однако вы должны позаботиться о том, чтобы правильно задокументировать состояние и поведение, которое определяет каждый суперкласс, поскольку этот код не будет отображаться в исходном файле каждого подкласса.

Однако в моем коде наследование не работает должным образом, возможно, из-за недостатка в моем коде?

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.

Есть идеи?

Ответы [ 8 ]

6 голосов
/ 18 декабря 2009

Нет, ваш класс 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 переменные для скорости и снаряжения. Рекомендуется применять инкапсуляцию, объявив переменные speed и gear private в базовом классе.


EDIT:

Очевидно, вы начинаете с программирования на Java. Я предлагаю вам взглянуть на эту бесплатную онлайн-книгу, написанную Брюсом Экелем: Мышление на Java .

5 голосов
/ 18 декабря 2009
public class Bicycle {
   private int speed;

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


public class Mountainbike extends Bicycle {
   public Mountainbike() {
      super(10);
   }
}
4 голосов
/ 18 декабря 2009

Вы не можете переопределить поля, только методы. Вам нужно пометить поле speed как protected, добавить конструктор в свой подкласс и установить значение поля в этом конструкторе, например:

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

Кстати, обратите внимание, что я исправил ваши имена классов: Java имеет чрезвычайно строгую конвенцию для имен классов в верхнем регистре; использование имен классов в нижнем регистре только запутает людей, которые смотрят на ваш код.

3 голосов
/ 18 декабря 2009

Вы ввели новую speed переменную в mountainbike, которая скрывает переменную в bicycle. Это плохая идея - наличие двух переменных с одинаковыми именами на разных уровнях иерархии типов приведет к путанице, особенно когда они обе доступны.

Вместо этого вы хотите изменить значение существующей переменной на 10. Например:

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

IMO поле должно быть действительно закрытым в базовом классе, а доступ к нему должен осуществляться через свойство - и, как уже сообщали другие, наличие в базовом классе конструктора, который принимает начальную скорость, также было бы хорошей идеей.

1 голос
/ 18 декабря 2009

Вы не можете переопределить поле, только методы.

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

class mountainbike extends bicycle {
    int getSpeed() {
        return 10;
    }
    // ... other things
}
1 голос
/ 18 декабря 2009

В Java существует понятие областей действия . То, что происходит, - то, что переменная скорости фактически не переопределяется, поэтому она по умолчанию имеет значение 0.

1 голос
/ 18 декабря 2009

На самом деле вы изменяете скорость поля в своем классическом горном велосипеде.

Например, вы можете начать скорость в конструкторе класса Mountainbike.

class mountainbike extends bicycle {
 mountainbike() {
   speed=10;
 }
}
0 голосов
/ 18 декабря 2009

Вы прячете bicycle.speed с помощью mountainbike.speed, поэтому в основном каждый экземпляр горного велосипеда имеет две переменные типа int для скорости: одна будет this.speed, а другая this.super.speed.

Вместо того, чтобы переопределять int speed внутри горного велосипеда, вам нужно просто создать конструктор по умолчанию для горного велосипеда и установить там this.speed = xxx;.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...