Genericsの型パラメータについて

このQ&Aのポイント
  • Genericsを使ったクラスの制約に関するエラーが発生しています。解決策を教えてください。
  • AクラスとBクラスの間で型制約の不一致エラーが発生しており、Genericsを使用した解決策をお求めです。
  • Genericsを使用して既存のクラスに制約を付ける方法を教えてください。エラーが発生しています。
回答を見る
  • ベストアンサー

Genericsの型パラメータ

Genericsについて質問します。既存のクラスにGenericsをつけるとエラーになってしまい困っています。 A、Bという抽象クラスがあり、互いに互いのサブクラスを限定したいフィールドを持つという前提で下記のようなコードを考えました。 が、b.setA(this);で 制約の不一致:型TのメソッドsetB(?)は引数(B<T>)に適用できません。 というエラーが発生してしまいます。(Bクラスも同様) その通りに、Bクラスの?をAに変えると警告が発生してしまい、さらに<?>を追加するとやっとなくなり、Aクラスも同様に修正すると両方ともクラスのパラメータ部でエラーが発生してしまいます。 Genericsを使用した解決策を教えてください。お願いします。 pakcage sample; public abstract class A<T extends B<?>> { private T b; public void setB(T b){ this.b = b; if(b.getA() == null){ b.setA(this); } } } pakcage sample; public abstract class B<T extends A<?> { private T a; protected void setA(T a){ this.a = a; a.setB(this); } protected T getA(){ return this.a; } }

  • Java
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.1

これは単純に、型の不一致(?とT extends A<?>など)という問題で、しかも無限の循環性を内包していますから、基本的に設計不良ということではないでしょうか。要求の詳細はよくわかりませんが、genericsを使わずに実装できるのでは?

bontabonta
質問者

お礼

回答有難う御座います。 >genericsを使わずに実装できるのでは? 実装できていました。Genericsを使ったらこのような状況になったのです。 こういう場合は無理にGenericsに対応しなくても良いのでしょうか?

その他の回答 (1)

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.2

だから、無限循環になってしまう設計不良だ、と申し上げました。このような処理にgenericsを使うメリットは何もありませんね。

bontabonta
質問者

お礼

同じ質問をして申し訳ありません。 Genericsに関しては初心者なもので機能を考えずに 適用させようとしていました。

関連するQ&A

  • GetterとSetterをやったのに。

    以下のプログラムを実行すると、フィールドA.aは不可視です。メソッドtestは型Aで不可視です。というエラーが出てきます。本に書いてあるとおり、やったのですが、どうしてダメなのかわかりません。ぜひ教えてください。 public class Sample { public static void main(String[] args) { A aa=new A(); System.out.println(aa.a); aa.test(); } } class A{ private String a = "A"; private void test(){ System.out.println("Test"); } public String getA() { return a; } public void setA(String a) { this.a = a; } }

    • ベストアンサー
    • Java
  • インタフェイス実装と抽象クラス継承を同時に使うには??

    私はjava初心者です、今練習問題で困っています。 1つのクラスに抽象クラスとインターフェイスを 実装することはできるのでしょうか? 例えば abstract class Car { private String gas; public void getGas(int gas) { this.gas = gas; } public abstract void enjin(); } interface Flying extends Pet { void show(); } 上のインタフェイスと抽象クラスを同時に下のクラスに継承、実装しよう とすると、どんな風にかけば良いのでしょうか class Zoon { public Zoon() { super(); } public void enjin() { System.out.println("どどどどど"); } public void show() { System.out.println("いいくるまだ"); } }

    • ベストアンサー
    • Java
  • 「オブジェクト志向」の考えかたで質問します。

    「オブジェクト志向」の考えかたで質問します。 いろいろと調べると、 ・繼承 ・カプセル化 ・ポリモーフィズム を総称したのが、「オブジェクト」志向と理解しています。 このとき、 たとえば、 指定するクラスの生徒の情報をとりだすようなソースをつくりたい。 仮に、以下をかんがえてみました。 DB処理は、省いてます。 //実行DAOクラス public class StudentDAO extends StudentDBAccessor{ //指定するクラスに属する生徒をとりだす public List getStudentList(int classNumber){ return super.getStudentList(); } //sql文生成 protected String createSqlSelectStudentList(){ StringBuffer sb = new StringBuffer(); return sb.toString(); } //キーワードを設定 public void setDataSqlStudentList(){ } } public abstract StudentDBAccessor extends DBConnector{ protected List getStudentList(){   //DBそうさ } protected abstract String createSqlStudentList(); protected void setDataSqlStudentList(int classNumber); } //DB接続クラス public class DBConnector{   //省略 } //Beanクラス public class StudentFormBean{ private int studentNumber; private String studentName; public void setStudentNumber(int number){ this.studentNumber = number; } public int getStudentNumber(){ return studentNumber; } } よろしくおねがいします。

    • ベストアンサー
    • Java
  • javaのGenericsが良く分かりません

    かなり以前に java プログラミングを少しばかりやっていたので java は少し分かるのですが、最近 また java プログラミング始めてみたのですが、Generics なる機能が「Java SE5.0から導入されたようですが、良く分かりません。 ご存知の方がいらしたら どうか ご教授下さいませm(_ _)m 開発環境 eclipse java 8 class Box<T> { // Object obj; T obj; @SuppressWarnings("unchecked") public T getT(){ return obj; } public void setT(T o){ obj = o; } @SuppressWarnings("unchecked") public void setTExtends(Box<? extends T> o){ obj = (T)o; } } Box<Number> boxN = new Box<Number>( ); Box<Integer> boxI = new Box<Integer>( ); boxN.setT((Number)new Integer(1)); // 当然、正常にコンパイルされる。 boxN.setT(new Integer(1)); // なぜか正常にコンパイルされる。 boxN.setT(boxN.getT()); // 正常にコンパイルされる。 boxN.setT(boxI.getT()); // なぜか正常にコンパイルされる。 boxN.setTExtends((Number)new Integer(1)); // なぜかコンパイル・エラーになる。 boxN.setTExtends(new Integer(1)); // なぜかコンパイル・エラーになる。 boxN.setTExtends(boxN.getT()); // なぜかコンパイル・エラーになる。 boxN.setTExtends(boxI.getT()); // なぜかコンパイル・エラーになる。 boxI.setT(new Integer(1)); // 当然、正常にコンパイルされる。 boxI.setT(boxI.getT()); // 当然、正常にコンパイルされる。 boxI.setTExtends(new Integer(1)); // なぜかコンパイル・エラーになる。 boxI.setTExtends(boxI.getT()); // なぜかコンパイル・エラーになる。

  •  型Containerのメソッドadd(String ,Compone

     型Containerのメソッドadd(String ,Component)は引数(JPanel ,String)に適用できません。  今晩は、java初心者です、エラーの意味が理解出来ません、宜しくお願い致します。  《A》というプログラムと《B》というプログラムで、クラスを「class MyPanel extends JPanel」と「class JPanel」に変えただけで、「型Containerのメソッドadd(String ,Component)は引数(JPanel ,String)に適用できません。」というエラーがでます。  一体何が原因でしょうか。  JPanelを継承したクラス(MyPanel)を呼び出すのか、そのまま、JPanelクラスを呼び出すのかの違いだけで、内容的には何も変わるところがないはずだと思うのですが。  意味が理解出来ません。 ======================================================================== 《A》 public class Sample extends JFrame { Sample() { this.setSize(300,200); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); MyPanel panel = new MyPanel(); this.add(panel , BorderLayout.CENTER); this.setVisible(true); } public static void main(String[] args) { new Sample(); } } class MyPanel extends JPanel { public void paintComponent(Graphics g) { g.setColor(Color.red); g.fillOval(50,50,100,100); } } ============================================================ 《B》 public class Sample extends JFrame { Sample() { this.setSize(300,200); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); this.add(panel , BorderLayout.CENTER); this.setVisible(true); } public static void main(String[] args) { new Sample(); } } class JPanel { public void paintComponent(Graphics g) { g.setColor(Color.red); g.fillOval(50,50,100,100); } } =======================================================================

    • ベストアンサー
    • Java
  • javaのprivate finalメンバについて、

    javaのprivate finalメンバについて、 public void setMember(SomeClass obj){ getMember.setA(obj.getA()); getMember.setB(obj.getB()); } のような値をコピーするだけのsetterを作るのはおかしいですか? finalなのは同一性を保証したいからつけていて、中の値は変えたいのですが、 参照する側にとってsetterは通常参照の置き換えを意味して分かりにくくなるのではと気になりました。 値をコピーする場合のsetterの名前の付け方などあるのでしょうか。

    • ベストアンサー
    • Java
  • ワイルドカード<?>と型パラメータ<T>の違いがすっきりしない。

    ワイルドカード<?>と型パラメータ<T>の違いがすっきりしない。 現在、Javaを勉強中の初心者です。一応、Cの心得はあります。 とりあえず、SJC-P資格の取得を目的として勉強していますが、どうも<?>のワイルドカードがすっきりと理解できません。というのも、Generics表記である<T>との違いが明確に区別できずにいるからです。 例えば、下のサンプルプログラムを例として、<T>と<?>の使い分けは、どのように頭を整理すればよいのでしょうか? Java初心者ゆえ、できるだけ難しい言葉は使わずに教えていただけると幸いです。 ---------------------------------------------------- class WildCardSample1<T>{ private T type; public WildCardSample1(T type){ this.type = type; } public void setType(T type){ this.type = type; } public T getType(); return type; } class WildCardSample1Main{ static void disp(WildCardSample1<?> w){ System.out.println(w.getType()); } public static void main(String[] args){ disp(new WildCardSample<String>("Tiger")); disp(new WildCardSample<Double>(5.0)); } }

    • ベストアンサー
    • Java
  • C++プログラミングをする上で、少々気になった点があるので質問させてく

    C++プログラミングをする上で、少々気になった点があるので質問させてください。 class CSuper { int _a,_b; public: CSuper(int a,int b); SetA(int a){ _a = a; } SetB(int b){ _b = b; } }; このようなクラスがある時 CSuper :: CSuper(int a, int b) : _a(a),_b(b) { } とするのと CSuper :: CSuper(int a, int b) { _a = a; _b = b; } とするのとでは、何か違いやメリット等はあるのでしょうか? また、 サブクラスのコンストラクタで CSub::CSub(int a, int b) : CSuper(a,b) { } とするのと、 CSub::CSub(int a, int b) { SetA(a); SetB(b); } とするのとでは、なにか違いはあるのでしょうか? よろしくお願いします

  • C++ protectedにアクセス不可

    C++でお聞きしたいことがあります。 初心者ですのでご容赦ください。 //基本クラス class a1 { protected: a1(); }; //派生クラス class a2 :public a1 { protected: a2():a1(){}; //継承先以外から作成されたくない int t; }; class a3 : public a2 //a2を継承 { public: a3(); ~a3(); private: a2* a; //a2のポインタを持つ }; a3::a3() { t = 3; a = new a2; //コンストラクタの中でnew } a3::~a3() { delete a; //終わったらdelete } int main(void) { a3 a; return 0; } というソースでa3はa2を継承しています。 ですのでa2のprotectedメンバtにアクセスできるはず。 ここまではいいのですが、 a2のコンストラクタもa3でアクセスでき無いのでしょうか? a3のコンストラクタでnewしようとすると error C2248: 'a2::a2' : protected メンバ (クラス 'a2' で宣言されている)にアクセスできません。 a2::a2' の宣言を確認してください。 というエラーが発生します。 やりたいのはa2のような基本クラスが6つほどあり、 a2のメンバ変数が多いので コンストラクタの引数で指定されたものだけ コンストラクタないでnewしたいのです。 なぜ、できないのか? どうすればnewできるようになるのか…。 非常にお手数ですが、 どなたかご回答いただけませんでしょうか? 長文になりましたが、宜しくお願いいたします。

  • 継承クラスで定義したメソッドのtry-catch文

    親クラスで、子クラスで実装されたメソッドのExceptionをキャッチしたいのですが、 うまくいきません。 何か良い方法はないでしょうか? abstract class A { public __construct(){ try{ $this->testA(); }catch(Exception $e){ var_dump(1); } } abstract function testA(); } class B extends A { function testA(){ throw Exception('test',1); } } try{ new B; }catch(Exception $e){ var_dump(2); // こっちが動く } よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう