例1
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List2<Object> list = new List2<>();
List<String> sList = new ArrayList<>();
List<Object> oList = new ArrayList<>();
list.merge(oList, sList);
}
}
class List2<E> extends ArrayList<E> {
public void merge(List<E> l1, List<E> l2){
this.addAll(l1);
this.addAll(l2);
}
}
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List2<Object> list = new List2<>();
List<String> sList = new ArrayList<>();
List<Object> oList = new ArrayList<>();
list.merge(oList, sList);
}
}
class List2<E> extends ArrayList<E> {
public void merge(List<E> l1, List<? extends E> l2){
this.addAll(l1);
this.addAll(l2);
}
}
例2
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
List2<String> list = new List2<>();
list.merge(new ArrayList<Object>());
}
}
class List2<E> extends ArrayList<E> {
引数のコレクションに要素を全て追加
public void merge(Collection<E> collection){
collection.addAll(this);
}
}
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
List2<String> list = new List2<>();
list.merge(new ArrayList<Object>());
}
}
class List2<E> extends ArrayList<E> {
引数のコレクションに要素を全て追加
public void merge(Collection<? super E> collection){
collection.addAll(this);
}
}
PECS
extendsの基準
メソッド内で入力された型パラメータの変数を使用する場合はextends
なんで?
メソッド内で入力された引数が、型パラメータに指定された型のサブクラスであった場合、親クラスとして使用しても問題ないから
superの基準
呼び出し元に返す(もしくは引数として破壊される対象)のオブジェクトにはsuper
なんで?
呼び出し元で型パラメータ化した変数にとって、その型パラメータのサブクラスを型パラメータ化した型として扱っても問題ないから
大事な前提条件
全ての子クラスは親クラスとしても使えなければならない(リスコフの置換原則)
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
ExtendsList<Child> list = new ExtendsList<>();
Collection<Object> objs = list.merge(new ArrayList<Child>());
}
}
class ExtendsList<E> extends ArrayList<E> {
public Collection<? super E> merge(Collection<? extends E> collection){
this.addAll(collection);
return this;
}
}
class Child extends Object{
}
class ChildChild extends Child{
}
これが通らないのは何故だろう
Collection
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class Test {
public static void main(String[] args) {
ExtendsList<Child, Object> list = new ExtendsList<>();
Collection<Object> objs = list.merge(new ArrayList<Child>());
}
}
class ExtendsList<E extends T, T> extends ArrayList<E> {
public Collection<T> merge(Collection<E> collection){
List<T> list = new ArrayList<>();
list.addAll(collection);
return list;
}
}
class Child extends Object{}
こんな感じにしたい場合は?
ExtendedListの型パラメータにObjectを指定しないでこれをできてもいいような
こんなん?
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class Test {
public static void main(String[] args) {
ExtendsList<Object> list = new ExtendsList<>();
Collection<Object> objs = list.merge(new ArrayList<Child>());
}
}
class ExtendsList<T> extends ArrayList<T> {
public Collection<T> merge(Collection<? extends T> collection){
List<T> list = new ArrayList<>();
list.addAll(collection);
return list;
}
}
class Child extends Object{}
ExtendsListのインスタンスを最初からChildで宣言するのは無理なのかな
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class Test {
public static void main(String[] args) {
ExtendsList<Child> list = new ExtendsList<>();
Collection<Parent> objs = list.<Parent>merge(new ArrayList<Child>());
}
}
class ExtendsList<T> extends ArrayList<T> {
public <E super T> Collection<E> merge(Collection<? extends E> collection){
List<E> list = new ArrayList<>();
list.addAll(collection);
return list;
}
}
class Parent{}
class Child extends Parent{}
なんとなくこんなんでいける気がするけどコンパイルが通らない