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

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

ただいまの
回答率

91.35%

  • Java

    10450questions

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

Javaのコードがわかりません。

解決済

回答 3

投稿 2017/11/21 00:00

  • 評価
  • クリップ 0
  • VIEW 238

97Ziq

score 1

Javaのコードがわからないので質問しました。

1.
クラスtestのinterface InterとクラスExpのInter aaaと書かれているのですが、何をしているのかわかりません。この処理の名称などがあれば、教えてください。

2.
Expのインスタンスを生成し、iやsから変数を参照、またはreturnで変数を返すことはできますか。


よろしくおねがいします。
public class test {
    public interface Inter
    {
        public int Pass();
    }

    class Exp{
        public Inter aaa(int i, int j, String s)
        {
            return null;
        }
    }
}

補足情報(言語/FW/ツール等のバージョンなど)

Java, Eclipse oxygen

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+3

何をしているのかわかりません

そもそも、ご質問のサンプルコードが、
何がしたいのか、意図が分かりにくいコードです。

「test」とか「aaa」とか名前が適当だし、
期待される返り値(の型)に反して、「null」を返しているとか、
いかにも書きかけっぽいです。お手本にすべきではありません。

元サンプルで大事なのは、インターフェイスだと思うので、
それが分かりやすくなるように、新サンプルを書き下ろしました。


public class Machine {
  public interface Bottle {
    public String open();
  }

  public Bottle select(int button) {
    Bottle product = null;
      if (button == 1) { product = new DrinkA(); }
      if (button == 2) { product = new DrinkB(); }
      return product;
  }

  private class DrinkA implements Bottle {
    public String open() {
      return "tea";
    }
  }

  private class DrinkB implements Bottle {
    public String open() {
      return "coffee";
    }
  }
}
class Client {
  public static void main(String args[]) {
    Machine vender = new Machine();
    int button = 1;
    Machine.Bottle product = vender.select(button);
    String result = product.open();
    System.out.println(result);
  }
}

上記サンプルコードを説明しますと、自動販売機をイメージしています。
購入者(クライアント)クラスから、自販機(マシーン)クラスを利用します。
ボタンを押すと、お茶かコーヒーが出てくるだけの、簡単な例です。

さて、インターフェイスがどのような意味を持っているかというと、
まず、「select」メソッドは、インターフェイス型の(参照する)値を返します。

今回の例では「Bottle」がインターフェイスで、「DrinkA」「DrinkB」が、
インターフェイスに規定された「open」メソッドを実装しています。

これによって、利用側の購入者クラスから、
IF文を消しているし、「DrinkA/B」という実装クラスも消しています。
これで、IF文で分岐して、newをベタ書きするのに比べて、メンテナンスしやすくなります。

なぜなら、インターフェイスで実装から分離されているので、
利用側のクラスを変更しないまま、実装クラスを交換できるからです。

それに今回の場合、「DrinkA/B」はprivateの内部クラスなので、
外部からインスタンスを勝手に作れないです。

これはひとりで書いていると意味が分かりにくいですが、
そもそもJavaは、企業が開発して、企業が利用している、大規模開発向け言語です。

そこで、自販機クラスを利用する側とされる側で、別人や別組織が実装している場合、
分離が非常に重要な意味を持ちます。利用する側にされる側の実装が入り込んでしまうと、
本体をクラスライブラリで拡張したいときなどに、本体がデグレする可能性が出てしまう。

だから、インターフェイスは実装が空だから、行数が多少増える、といった些細なことより、
実装から分離することの方が大事なんです。インターフェイスはJavaの中心的な機能です。
GOFも「(実装ではなく)インターフェイスに対してプログラミングせよ」と言っています。

デザインパターンを研究すると、こういう仕組みはよく分かります。
詳細は省きますが、上のコードはファクトリ(メソッド)パターンを使ってます。


Machine.Bottle product = vender.select(button);

もう少し裏側も見ておくと、インターフェイスで実装を切り離すことで、
利用側からIF文などが消えて宣言的に読めるのもメリットです。

上の一行を適当に意訳して読み下すと、
「販売機のボタンを選択した結果が、自販機向け飲料の製品である」
となります。翻訳調で不自然な日本語ですが、大筋の意味は通ると思います。

さらにたとえば、自販機にコインを投入する機能をつけたとして、
1年後に読んでも、「Bottle」と「Money」を取り違えることはまずないでしょう。
これが、「aaa」と「bbb」とかだと、どっちがどっちだか、すぐ分からなくなります。
書いているときは覚えていても、長期間に渡って保守すると負債になってきます。

また、名前が「aaa」などだと意味が分からないので、毎回実装を読む必要があります。
しかし、大規模はコード量が大量なので、なるべく実装を読まないで使いたい

これには違和感があるかもしれませんが、標準ライブラリなどは、なるべく読みたくないでしょう。
それなら、自分たちのコードを標準ライブラリに近づければ、組みやすくなります。

ドメインの言葉、業務の言葉、今回なら自販機を利用するシーンの言葉に近づけると、
利用しやすいし、変更しやすくなります。人間が理解しやすいからです。

まあサンプルなので、この例自体は微妙かもしれませんが、少なくとも、
質問文のサンプルコードの「aaa」とかよりは確実にマシだと思います。

もちろん、本番で書くときは、余裕さえあれば、ここからもっと、
ドメインに沿った命名にリファクタリングしていきます。


今回、「内部クラス(インナークラス)」や「ネストした型」に関しては、省略しました。
解説が中途半端にならないよう、インターフェイスの方を優先しました。

内部クラスはわりとマニアックな文法なので、下記リンクの解説記事に譲ります。
(ただもし、クラスが作れない環境とかだと多用せざるをえないかも……)

投稿 2017/11/21 19:04

編集 2017/11/21 22:02

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/22 00:17

    インターフェイスについて詳しい解説、コードありがとうございます。

    public Bottle select(int button) 

    について質問なのですが、selectメソッドの型(void , int , string)はどうなっているのですか?

    キャンセル

  • 2017/11/22 00:25

    >selectメソッドの型
    selectメソッドは、intの引数を取り、Bottleインターフェイス型の値を返します。
    サンプルコードの中で具体的には、DrinkAとBがBottle型に相当し、実際返してます。

    なぜ、その型になるかというと、Bottleをimplementsしてるからです。
    特定の組織の構成員になって、通行許可証をもらえるみたいな感じで、
    インターフェイスを継承すると、その型を使える。つまり型も継承しています。

    キャンセル

  • 2017/11/22 01:21

    なるほど。
    詳しい解説で、スッキリしました!

    質問に答えて頂きありがとうございます。

    キャンセル

0

どの処理が分からないのかご質問の内容から理解しきれていないかもしれませんが、
InterインタフェースやExpクラスはtestクラスの内部インタフェースや内部クラス(インナークラス)と呼ぶものかと思います。
ExpクラスのaaaメソッドはInterインタフェースの値を戻り値として定義している、通常のメソッド宣言です。
インスタンスの生成は下記のように行えるかと思います。
下記ではTestクラスとクラス名を大文字で始めるようにしています。

public class Test {
    public interface Inter
    {
        public int Pass();
    }

    class Exp{
        public Inter aaa(int i, int j, String s)
        {
            return null;
        }
    }
}
class Main {
    public static void main(String args[]) {
       Test test = new Test();
       Test.Exp exp = test.new Exp();
       Test.Inter inter = exp.aaa(1, 2, "");

       System.out.println(test);
       System.out.println(exp);
       System.out.println(inter);
    }
}

/*
$ java Main
Test@6073f712
Test$Exp@43556938
null
*/

追記:

コメントでの指摘を受け、表現を修正しています。

  • サブインタフェース → 内部インタフェース
  • サブクラス → 内部クラス(インナークラス)

投稿 2017/11/21 02:52

編集 2017/11/21 09:31

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/21 09:18

    「サブ」は一般に「派生」を意味する気がするので本件の意味には用いない方がよいと思います。言語仕様書では以下が用いられていると思います。

    Inter=>nested interface
    Ext=>inner class(staticでないnested classのこと)

    キャンセル

  • 2017/11/21 09:31 編集

    ご指摘ありがとうございます。
    確かに内部クラス等の方が適切ですね。
    指摘頂いてサブクラスは継承関係等で用いる言葉だと私も思い至りました。

    キャンセル

  • 2017/11/21 09:37

    上記で書かれているように、Interインターフェイスはサブ・インターフェイスではないし、Expクラスはサブ・クラスではありませんね。
    あと「Interインタフェースの値」というのは、とりわけ初心者に対しては誤解を招く表現だと思います。正しくは「Inter型の参照」としたほうがよいでしょう。もし質問者が「参照」の意味が分からないのであれば、まずはそこから勉強して理解すべきです。

    キャンセル

  • 2017/11/21 10:30

    プログラミングをJavaなどで始めた初心者の方に対して「値」という用語をprimitive型の値、「参照」をreference typeの値として説明した方が誤解を招きにくいという意見はあるかと思います。ただ、その用語の区別を徹底すると「変数の値」「メソッドの戻り値」とはいえず「変数の値または参照」「メソッドが返す値または参照」と言わないといけないことになる気がします。それは大変煩雑な表現なので、初心者に対しても

    「値」には「プリミティブ型の値」と「参照型の値」の2種類ある

    と理解してもらった方がベターであるというのが自分の意見です。

    言語仕様書の章タイトルの例を挙げると
    4.1 The Kinds of Types and Values => 「型と値」
    4.2 Primitive Types and Values => 「プリミティブ型と値」
    4.3 Reference Types and Values => 「参照型と値」

    https://docs.oracle.com/javase/specs/jls/se9/html/jls-4.html#jls-4.3

    キャンセル

  • 2017/11/21 11:19

    プリミティブも参照も、どちらも「値」として扱われるという部分は仰る通りです。インターフェイス「型」の「参照値」ということをきちんと理解できるように、というニュアンスでの指摘でした。少し言葉足らずで申し訳ありませんでした。

    キャンセル

  • 2017/11/21 11:25

    「正しくは」の一言だけが気になっただけです。細かい話で恐縮です。

    キャンセル

  • 2017/11/22 00:24

    内部クラスや内部インターフェイスなど処理の名称を教えて頂き、ありがとうございます。

    キャンセル

0

「書かれているのですが、何をしているのかわかりません」

とあるため、おそらくこのコードは質問者自体が書いたコードではないと推測されますが、一体何を参考にしたのですか? 実際のプログラムとしてはまったく意味のないコードが書かれており、単に入れ子のインスタンスや内部クラスの仕組みを試そうとするだけのもののような気がします。
まず、入れ子のインターフェイスや内部クラスが理解できていない段階であれば、トップレベルの独立したインターフェイスやクラスにした方がいいでしょう。

Expのインスタンスを生成し、iやsから変数を参照、またはreturnで変数を返すことはできますか。

メソッドからreturnで返されるのは常に何らかの「値(もしくは参照)」です。「変数を返す」ということはできません。変数に代入されている値を返すことはできますが。

投稿 2017/11/21 09:50

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/22 00:18

    解説ありがとうございます。

    内部クラスやインターフェイスなど、Javaについてもっと勉強しようと思います。

    キャンセル

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

ただいまの回答率

91.35%

関連した質問

  • 受付中

    計算機のプログラム

    初めて質問投稿します。質問に対して不足している情報などあるかもしれませんが、ご容赦ください。 Javaで簡単な計算機の仕組みを作ろうとしています。 しかし、いざコンパイルしようと

  • 解決済

    javaでデータを読み込んでソートしたいのですがうまく来ません

    コンパイルするとエラーになって 「シンボルが見つかりません」と表示されます。 他にも問題があれば教えてください import java.io.File; import

  • 解決済

    文字列バッファについて

    言語はJavaにしていますが、Javaに限った話ではありません。 私が勉強している本で次のような記述がありました。 「文字列のリストを連結するときを考えます。すべての文字列

  • 解決済

    以下の状況での再利用性

    http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-2.html こちらのサイトを参考にし

  • 解決済

    クラス型配列のフィールドにアクセスしたいです。

    前提・実現したいこと サイコロが同じかどうかをチェックするプログラムです。 サイコロがn個与えられ、サイコロ各面に任意の数字が割り振られます。 サイコロDiceは_d[6]を

  • 解決済

    Java

    public class Mai{ public static void main(String[] args){ int x = 10;

  • 解決済

    jmockit1.3でメソッドのみをモック化したい

    例えば、AClassのメソッドであるAmethodのみをモック化したい場合、過去のバージョンでは、以下のような指定で実現できました。 @Mocked("Amethod") A

  • 解決済

    JFrameでのJPanelの切り替えについて

    前提・実現したいこと (例)Java(UIはJFrame)でゲームを作っているのですが、JPanelの切り替えをJFrameで行おうとしています。 しかし、JPanelの切り替

同じタグがついた質問を見る

  • Java

    10450questions

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