Переменная видимость в подклассе - PullRequest
2 голосов
/ 10 ноября 2010

Это очень простой вопрос, и я прошу прощения за то, что был таким нубистским: /

Я новичок в Java. У меня есть игра на Маркете, которая работает довольно хорошо, но код - все ерунда. По сути, я написал это так, как будто пишу JavaScript. Я пытаюсь узнать больше об объектно-ориентированном программировании. Итак, в моей новой игре я создаю Объекты, которые выходят из пользовательского класса. Например (на самом деле это не то, что я делаю):

public class Color{
    public final int STROKE_WIDTH = 3;

    public Color(){}
}


public class Orange extends Color{
    public int alpha = 30;

    public Orange(){
        super();
    }
}

Теперь, скажем, в основной теме моей игры я создаю множество цветов (оранжевый, красный, фиолетовый) и сохраняю их в ArrayList<Color>. Я перебираю этот список в другой точке игры и хочу получить доступ к альфа-версии Color. Моя проблема в том, что, поскольку они все заключены в суперкласс, я не могу просто сказать colorObj.alpha, но у меня есть доступ к colorObj.STROKE_WIDTH. Точно так же я не смог бы получить доступ ни к каким методам в классе Orange.

Должен быть способ сделать это, я просто новичок. Я не ожидаю, что кто-нибудь сядет здесь и наберет объяснение .. Я не хотел бы тратить ваше время. Но если бы кто-то мог просто вставить ссылку на учебник для начинающего или что-то, что помогло бы мне с этим, я был бы признателен за это!

Ответы [ 3 ]

1 голос
/ 10 ноября 2010

Я перебираю этот список в другой точке игры и хочу получить доступ к альфа-версии Цвета.Моя проблема в том, что, поскольку они все заключены в суперкласс, я не могу просто сказать, что colorObj.alpha

Если у всех ваших реальных цветов есть альфа, то поместите это в класс Color.Он должен содержать атрибуты и поведение, общие для всех цветов.

Примечание: один из тентов объектно-ориентированного программирования - enscapsulation .Открытые члены данных предоставляют внутреннее представление вашего класса.Обычно вы скрываете это представление за методами accessor , такими как:

class Color {
   private int alpha;
   public int getAlpha() { return alpha; }
}

Теперь никто не знает ваше представление;никто не может изменить альфа на значение, которое не имеет смысла для цвета, вы можете сделать его доступным только для чтения или только для записи, вы даже можете изменить его на вычисленное значение, и ни один из клиентов, которые его используют, не затронут.

Фактически, «лучшая практика» в ООП сводит это к крайности и программирует для интерфейсов, а не классов.Вы должны определить интерфейс для цветов, который не имеет элементов данных и фактически не может быть создан.Он представляет контракт, которому подчиняются Цвета, и ничего более.Например:

interface Color {
   int getR();
   int getG();
   int getB();
   int getA();
}

class Red implements Color {
   ...

Конечно, это излишне для чего-то вроде цвета.Я знаю, что это надуманный пример, но у цветов нет другого поведения , просто разные значения , поэтому вместо классов Red, Orange и т. Д. У вас будут экземпляры Colorкласс, который представляет каждый.

Точно так же я не смог бы получить доступ к любым методам в классе Orange.

True.Но идея состоит в том, что коду, который имеет дело с цветами, не нужно знать , какие они на самом деле цвета.Это сила полиморфизма.Если для есть требуется некоторая обработка в специальном случае, вы можете «понижать» цвет до определенного подтипа, но необходимость в этом часто является признаком небрежного дизайна.

1 голос
/ 10 ноября 2010

Если вы напишите:

Color c = new Orange();
c.alpha = 10; // Won't compile

Это не скомпилируется не потому, что альфа обернута, но вы должны определить это в суперклассе. Точно так же все методы, определенные в Orange, недоступны в приведенном выше объявлении, потому что, когда вы ссылаетесь на «c», это означает, что это Color, но это не обязательно Orange. Подводя итог, обозначение «c» в вышеприведенном объявлении позволяет вам получить доступ ко всем открытым членам Color, но НЕ к членам Orange.

Изучать ООП непросто, особенно для людей, пришедших из Script dev. Вместо того, чтобы просто читать онлайн-материалы, я предлагаю вам начать с хорошей книги об ООП или Java. Серия Head First - одна из тех, которые я настоятельно рекомендую.

0 голосов
/ 10 ноября 2010

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

Позже, если вы хотите получить доступ к методам или переменным, специфичным для унаследованного класса, вы должны выполнить приведение, так что если у вас есть List myColors;и скажем, что i-й объект в списке имеет оранжевый цвет, и у него есть метод с именем mix (Color otherColor), тогда вам нужно просто сделать это:

((Orange)myColors.get(i)).mix(someOtherColor);

И последнее, не используйтепеременные-члены открытого класса, всегда дают им наименьшую возможную видимость (приватную, защищенную) и всегда используют геттеры для доступа к ним и сеттеры для их изменения, поскольку это очень базовая концепция ОО:)

...