简体   繁体   中英

Java creating devired class from base

Let's say I have a base class:

Class A {
    public String field1;

    public A(String field1){
        this.field1 = field1;
    }
}

And a devired class:

Class B extends A {
    public String field2;
}

Let's say I have a List<A> listA , how can I create a constructor so I can easily turn this list to List<B> listB ? I want to have a constructor in B class that will take A object and fill in all the fields from A in B and have some logic to construct new fields. Something like this:

Class B extends A {
    public String field2;

    public B (A a){
        this = a;
        this.field2 = doLogic(a);
    }
}

Or at least just fill in all the fields from A in B:

public B(A a){
    this = a;
}

So later I can just manually set the field from B , to something like this:

listA.stream().map(x -> new B(x)).map(x -> x.setField2(logic(x)));

I know I can do it like this:

Class B extends A {
    public String field2;

    public B(A a){
        super(a.getField1());
    }
}

But this just doesn't look right to me, getting the fields of the object just to call a constructor of the same class.

What if the base class has a lot of fields, will you need to get all of the fields to call in the constructor? It doesn't look good, so I'm wondering if is there any better way.

What if the base class has a lot of fields

The first question of course would be why you need that and whether there might be another way. In this answer I'll assume you've already answered that question and came to the conclusion you need it.

Let's say I have a List<A> listA , how can I create a constructor so I can easily turn this list to List<B> listB ?

You could do a copy constructor and maybe also do something like this:

class A { 
  A(A other) {
    //copy fields
  }
}

class B extends A {
  B(A other) {
    super(other);
    //init B fields
  }
}

With this in place you can use plain iteration or streaming to turn a List<A> into a List<B> :

List<B> convertedList = origList.stream().map(a -> new B(a)).collect(Collectors.toList());

Another option might be delegation but that would depend on your classes:

class B extends A {
  A delegate;      

  B(A delegate) {
    this.delegate = delegate;
    //init B fields
  }

  @Override
  void setField1(String value) {
    delegate.setField1(value);
  }

  @Override
  String getField1() {
    return delegate.getField1();
  }
}

Doing it like this would leave B's "field1" empty so it might not be the best option. If you have an interface for A it would look similar but leave less "empty" fields:

interface AInterface {
  void setField1(String value);
  String getField1();
}

class A implements AInterface {
   ...
}

class B implements AInterface {
  AInterface delegate;
  
  B(AInterface delegate) {
     this.delegate = delegate;
    //init B fields
  }

  @Override //this is not an actual override but an implementation
  public void setField1(String value) {
    delegate.setField1(value);
  }

  @Override //this is not an actual override but an implementation
  public String getField1() {
    return delegate.getField1();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM