Нужно ли использовать композицию и агрегацию при создании нестатического вложенного класса?

 
 
 
Сообщения:73
Нестатические вложенные классы нужны для тех случаев, когда класс создается как часть другого класса(чтобы много классов со схожими названиями не создавать, aka carWheel,bicycleWheel и тд)(эстетика) или когда класс много где использует переменные внешнего класса(тех. часть). Более они от обычных классов ничем не отличаются(кроме запрета на создание static переменных и static методов).
На основании этих данных всплывает вопрос - что я теряю при использовании композиции и агрегации:

class Bicycle{
    Wheel wheel;
    Bicycle(int степеньНакачкиКолес/*и другие переменные*/){
        wheel = new Wheel(степеньНакачкиКолес);
        /*и другие переменные*/
    }
    Bicycle(/*другие переменные*/){
        wheel = new Wheel();
        /*другие переменные*/
    }
    class Wheel{
        int степеньНакачкиКолес;
        Wheel(int степеньНакачкиКолес){
            this.степеньНакачкиКолес = степеньНакачкиКолес;
        }
        Wheel(){
            степеньНакачкиКолес=0;
        }
        void weGotDamage(){
            toStopEveryThing();//мы имеем доступ к переменным и методам внешнего класса!
        }
    }
    void toStopEveryThing(){
        //code
    }
    public static void main(String[] args){
        Bicycle bicycle = new Bicycle(500);
        bicycle.wheel.weGotDamage();//вызываем метод объекта wheel toStopEveryThing();
    }
}


По сравнении с этой реализацией:

class Bicycle2{
    Bicycle2(){}
    class Wheel{
        int степеньНакачкиКолес;
        Wheel(int степеньНакачкиКолес){
            this.степеньНакачкиКолес = степеньНакачкиКолес;
        }
        Wheel(){
            степеньНакачкиКолес=0;
        }
        void weGotDamage(){
            toStopEveryThing();//мы имеем доступ к переменным и методам внешнего класса!
        }
    }
    void toStopEveryThing(){
        //code
    }
    public static void main(String[] args){
        Bicycle2 bicycle = new Bicycle2();
        Bicycle2.Wheel wheel = bicycle.new Wheel(500);
        wheel.weGotDamage();//Оно свяжется с bicycle и вызовет метод toStopEveryThing();
    }
}
 
 
Сообщения:101
Мне кажется в данном примере уместнее первый вариант. Колесо - внутренний класс у велосипеда. Он нужен только велосипеду. Не нужно открывать его наружу. Зачем пользователю вашего апи(велосипеда) уметь работать с колесом? Я считаю, ему нужен ваш велосипед, а уж о внутренней структуре(особенности ключевых узлов) знать не обязательно. Поэтому велосипед сам должен работать с колесом, а наружу если нужно отдавать релевантный метод. Это больше ООП.
 
 
Сообщения:73
А есть примеры, где уместнее использовать второй вариант? Какие-то преимущества у него есть?
 
 
Сообщения:101
Может конечно прозвучит странно, но обратная ситуация. Мне кажется зависит от дизайна конкретного приложения. Например, вам нужно, что пользователь вашего велосипеда мог сетапить разные колеса - потолше/потоньше. Колесо же можно сделать интерфейсом или абстрактным классом. И писать колеса - какие душе угодно.
Изменен:17 мая 2019 12:40
 
 
Сообщения:73
Так класс наследника(myObj, ваше модифицированное колесо) можно преобразовывать в класс суперкласса(WrappedObjectParent, класс колеса, шаблон):

class forTest{
    WrappedObjectParent wrappedObjectParent;
    forTest(WrappedObjectParent wrappedObjectParent){
        this.wrappedObjectParent = new WrappedObjectParent(wrappedObjectParent);
    }
}
class WrappedObjectParent{
    int x;
    WrappedObjectParent(){
        this.x=10;
    }
    WrappedObjectParent(int x){
        this.x=x;
    }
    WrappedObjectParent(WrappedObjectParent wr){
        this(wr.x);
    }
}
class myObj extends WrappedObjectParent{
    myObj(){
        super();
    }
    myObj(int x){
        super(x);
    }
}


И main:

myObj m = new myObj(20);
forTest ft = new forTest(m);
Изменен:17 мая 2019 16:01
 
Модераторы:frymock
Сейчас эту тему просматривают:Нет