質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

1回答

3474閲覧

【Java】インナークラスで外部クラスのメソッドを使用する方法。

wamiota

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2019/06/02 12:51

編集2019/06/02 14:03

以下の3つのクラスがあると仮定して、HogeクラスでHogeHogeインスタンスを作成するときにFooクラスのメソッドを呼び出そうとするとis not an enclosing class.のエラーが出てしまいます。
どうすればFooクラスのメソッドをprintHogeHoge()メソッドで使用できるようになるでしょうか。

Hoge

1public class Hoge { 2 3 public static void main(String args[]){ 4 Foo f = new Foo() { 5 @Override 6 public void printFoo() { 7 HogeHoge hoge = new HogeHoge() { 8 @Override 9 public void printHogeHoge() { 10 Foo.this.printFoo(); 11 System.out.println("オーバーライドしたよ。"); 12 } 13 }; 14 } 15 }; 16 } 17}

Foo

1public class Foo { 2 3 public void printFoo() { 4 System.out.println("Fooクラスのメソッド"); 5 } 6}

HogeHoge

1public class HogeHoge { 2 3 public void printHogeHoge() { 4 System.out.println("HogeHogeクラスのメソッド"); 5 } 6}

追記
printFooメソッドをstaticにすることなく使用できるようにしたいです。

さらに追記
すみません!問題が若干違っていました!
printFoo(){}内でオーバーライドします、、

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

原因の特定

まず問題を単純化するため、次のようなコードに書き換えてみました。

Java

1public class Hoge { 2 public static void main(String args[]){ 3 Foo f = new FooFoo(); 4 } 5 6 static class FooFoo extends Foo { 7 HogeHoge hoge = new HogeHoge() { 8 @Override 9 public void printHogeHoge() { 10 Foo.this.printFoo(); 11 System.out.println("オーバーライドしたよ。"); 12 } 13 }; 14 } 15}

するとやはり not an enclosing class とのエラーが出ます。
この例の場合、外部クラスはFooFooで有りFooでは無いからだ、ということは明白に分かります。

実際に次のように書き換えると、エラー無くコンパイルできます。

Diff

1- Foo.this.printFoo(); 2+ FooFoo.this.printFoo();

これを踏まえて元のコードを見直すと、
fはあくまでFooを継承した匿名クラスのインスタンスであることに目が向きます。

hogeのenclosing class(外部クラス)はFooでは無いのです。Fooを継承したクラスです。
しかし匿名クラスの名前はコンパイル時には知り得ません。

エラーの解消

java anonymous enclosing class」とググったところ、ドンピシャな質問を見つけました。

##How to access “this” reference of anonymous outer class in java
...

###1 Answer
You cannot access an instance of anonymous class directly from inner class or another anonymous class inside it, since the anonymous class doesn't have a name. However, you can get a reference to the outer class via a method:

Java

1new Outer() 2{ 3 public Outer getOuter() 4 { 5 return this; 6 }
public void outerMethod() { new Inner() { public void innerMethod() { getOuter().hashCode(); } }; }

};

引用元:StackOverflow - How to access “this” reference of anonymous outer class in java

五年近く前のQAですから、ともすれば今のJavaならもっとスマートな解決策があるかもしれません。
しかしこの方法でもある程度簡潔な解決策になっているようには思います。

評価について

@低評価された方
もちろん評価は自由にしていただいて構わないのですが、思い当たる節がありません。
回答を訂正及び改善していくために、低評価の事由をお伝えいただけないでしょうか。

投稿2019/06/02 13:42

編集2019/06/03 22:55
LouiS0616

総合スコア35676

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wamiota

2019/06/02 14:00

ありがとうございます。 メソッド内でオーバーライドする場合に問題が変わったので、再度ご確認いただけますと幸いです、、
LouiS0616

2019/06/02 14:21

確認しましたが、原因も対策も同じです。 printFoo内の匿名クラスのメソッドがprintFooを呼んでいるのがバグを生みそうでちょっと気掛かりですが。
退会済みユーザー

退会済みユーザー

2019/06/03 23:04

(ラッパークラス).this.(変数 or メソッド) が使えるのが「内部クラス」だけであって「スタティックな内部クラス」では利用できないが仕様だったはずだけど。 そのあたりで下げられたのでは?
退会済みユーザー

退会済みユーザー

2019/06/03 23:59

原因の特定 static class FooFoo extends Foo
退会済みユーザー

退会済みユーザー

2019/06/04 00:03

ぱっと見だけどね。
LouiS0616

2019/06/04 03:12

Hoge.this ができないだけで、 回答の本旨は崩れていないと思います。 とはいえ、あたかも等価なコードのように書いているのは不適切ですね。取り急ぎ訂正しておきます。ご指摘ありがとうございます。
LouiS0616

2019/06/04 03:16 編集

あれ、しかしstaticメソッド内で生成された匿名クラスは外部クラスのインスタンスへの参照を持ち得ないのでは? そうなるとstaticクラスで再現するのが適切なように思います。
退会済みユーザー

退会済みユーザー

2019/06/04 03:19

static メソッド内で作成された場合 static なクラス扱いですよ
LouiS0616

2019/06/04 03:21

ですよね。 でしたら static class FooFoo extends Foo で全く問題無いのでは?
xebme

2019/06/04 10:30

初めて低評価しました。お調べになった内容は正しいです。しかし質問に惑わされたと思ったのです。 Foo.this.printFoo();の代わりに、printFoo(); を検討しても良かったのではないかと思ったからです。 低評価を撤回します。もう二度と低評価しません。
LouiS0616

2019/06/04 11:16

@xebme さん なるほど。確かにthisを参照する意義は薄いですね。 xebmeさんのお考えを回答として書かれてはいかがでしょうか。 > もう二度と低評価しません。 何か委縮させてしまったならごめんなさい。 評価自体は自由にして頂いて良いんです。 ただ私自身が学ぶ目的で回答している面もあるので、どのような指摘があるのか気になるだけなのです。
xebme

2019/06/04 11:52

低評価をつけたのはなさけないと思います。おっしゃるとおり、低評価だけでは理由がわからずフェアでない。だからやめます。 回答はしません。言語そのものへの関心が薄れつつあるので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問