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

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

ただいまの
回答率

90.34%

  • Java

    14396questions

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

インタフェース、抽象クラスについての問題がわかりません。

解決済

回答 2

投稿

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

wakataku1318

score 11

前提・実現したいこと

javaを使用した課題に取り組んでいます。
インタフェース、抽象クラスを使用して以下の実行例通りに表示をしたいです。
[実行例]
$javac Kadai64.java
$java Kadai64
24インチディスプレイ:60000

またmain関数の中の手順が以下になります。

  1. MyFactory
    クラスのオブジェクトを作成し,参照をFactory型の変数fに代入する
  2. f引数に与え,FactoryViewerクラスのオブジェクトを作成し,参はVisible型の変数vに代入する
  3. vを用いてviewメソッドを実行する

おそらくtoString()メソッドの戻り値がうまく返せていないので、違う結果になっていると思うのですが、解決方法がわかりません。
また参照変数についてもよく理解できていません。

発生している問題・エラーメッセージ

Kadai64.java:48: ';' がありません。
        return product:price;
                      ^
Kadai64.java:48: 文ではありません。
        return product:price;
                       ^
エラー 2 個
(以上の文章を以下のように変更して、実行した結果)
return "product:price";

FactoryViewer@3bba1894

該当のソースコード

public class Kadai64 {
    public static void main(String arg[]) {
        MyFactory f = new MyFactory("24インチディスプレイ",600000);
        FactoryViewer v = new FactoryViewer(f);
        v.view();
    }
}

/**
*Factory抽象クラス
*/
abstract class Factory{

    /**
    *フィールドを文字列にして戻す抽象メソッド
    */
    abstract public String toString();
}

class MyFactory extends Factory{
    /**
    *製品名を表します
    */
    protected String product;

    /**
    *価格を表します
    */
    protected int price;

    /**
    *参照変数を表します
    */
    protected Factory f;

    /**
    *製品名、価格を引数にとるコンストラクタ
    */
    public MyFactory(String pro,int pri){
        product = pro;
        price = pri;
    }

    /**
    *”製品名:価格”の文字列で返すコンストラクタ
    */   
    public String toString(){    
        return "product:price";
    }
}
/**
*表示する性質をクラスに付加するインタフェースVisible
*/
interface Visible{
    /**
    *表示する抽象メソッド
    */
    abstract void view();
}

/**
*Factoryの内容を表示するクラスFactoryViewer
*/
class FactoryViewer implements Visible{

    /**
    *フィールドの値を引数に受け取るコンストラクタ
    */
    public FactoryViewer(Factory f){
    }

    /**
    *toStringメソッドの戻り値を表示するメソッド
    */
    public void view(){
         System.out.println(toString());
    }
}

試したこと

エラー箇所をエラーにならないように変更してみた。

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

java言語

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

ソースを一読させていただきました。初学者のようなので仕方がないことだと思いますが、まだまだ基本的理解が未熟な印象を受けます。
まず、 String product と int price の値を "[productの値]:[priceの値]" として連結した文字列を返すメソッドを例としておいておきます。

public String test() {
    String product = "24インチディスプレイ";
    int price = 600000;

    return product + ":" + price;
}


実を言うと、このやりかたはあまり好まれないのでStringBuilderというものを使うのですが、それはもうすこし学習が進んでからでしょう。(私的の開発では面倒で省いちゃいますが 笑)

また

/**
*Factory抽象クラス
*/
abstract class Factory{

    /**
    *フィールドを文字列にして戻す抽象メソッド
    */
    abstract public String toString();
}


とありますが、とくに理由がなければinterfaceで書くべきです(課題ということなのでわざとですかね?)
interfaceはすべて抽象メソッドですが、抽象クラスはabstractではないメソッドも記述できます。
もし課題かなんかの関係で、これを抽象クラスとして運用させたい場合、なんらかのフィールド(変数)を持たせておいてください。それが正しい抽象クラスの使い方です。
抽象クラスは、ある程度の骨組みを作っておき、そこから拡張していくためのものです。
interfaceは、それひとつで性質を示すことができ、これらを実装するすべてのクラスの共通性質を示すことができます。そういうわけでinterfaceを実装するクラスはそれをすべて実装しなければコンパイル・エラーとなります(いいかえればさっき述べたようにすべてabstractのメソッドです)。まだその使いみちはわからないかもしれませんが、気づいた時にはなんて便利なものだと思うでしょう。
またinterface内ではabstractを明示する必要がありません。
ですので、

/**
*表示する性質をクラスに付加するインタフェースVisible
*/
interface Visible{
    /**
    *表示する抽象メソッド
    */
    abstract void view();
}


これを、

/**
*表示する性質をクラスに付加するインタフェースVisible
*/
interface Visible{
    /**
    *表示する抽象メソッド
    */
    void view();
}


と書きかえると可読性が上がると思います。好きな方で構いませんが。
また抽象メソッドをオーバーライドをする際には、以下のように@Overrideアノテーションをつけると良いでしょう。
間違いをコンパイルの段階で検出してくれます。アノテーションについて詳しいことはまだわからなくてもいいと思います。

@Override  
public void implementation_required() {
    return;
}

ちょっと長くなってしまっていますが、あともう少しお時間をください。
Visible の実装で toString() を用いていますが、 toString という名前を使用は回避すべきです。
なぜなら、 java.lang.Object ですでに定義されているからです。 java.lang.Object はすべてのクラスのスーパークラスです。詳しくはJavaのDocumentationをごらんください → java.lang.Object
そして最後に重大な問題ですが、

/**
*Factoryの内容を表示するクラスFactoryViewer
*/
class FactoryViewer implements Visible{

    /**
    *フィールドの値を引数に受け取るコンストラクタ
    */
    public FactoryViewer(Factory f){
    }

    /**
    *toStringメソッドの戻り値を表示するメソッド
    */
    public void view(){
         System.out.println(toString());
    }
}


view()内で正しく参照が行われていません。これではFactoryViewerのインスタンスのtoString()が呼び出されてしまっています。(これは前述の通りObjectから継承されたものです、FactoryViewerの文字列表現が返ってきているのがわかると思います)期待する動作を実現するためにはこのようにしてください。

/**
*Factoryの内容を表示するクラスFactoryViewer
*/
class FactoryViewer implements Visible{
    private Factory factory;

    /**
    *フィールドの値を引数に受け取るコンストラクタ
    */
    public FactoryViewer(Factory f){
        factory = f;
    }

    /**
    *toStringメソッドの戻り値を表示するメソッド
    */
    public void view(){
         System.out.println(factory.toString());
    }
}


以上のことを改善すれば動作しますが、あと2点だけお知らせしておきたいことがあります。
命名に関してですが、「FactoryViewer」の実装が「Visible」だと混乱します。
Viewer→見るもの
Visible→可視
のように、意味が離れているため、どのような実装が第三者から推測できず混乱します。
「Visible」は「Viewer」に改めるべきです。
またコンストラクタの記述ですが、以下のようにできます

public class Test {
private int value;

    public Test(int value) {
        this.value = value;
    }
}


あとどうして protected にしているのか...? と気になる部分はありますが
アクセス修飾子について書くと本題からそれすぎるため書けません、これに関しては別途質問するなりご自分で調べてください。
以上です。ご不明な点があればお知らせください

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/01/05 23:20

    > String型ではない変数をString型で返すには、String型に変換する必要があります。この型変換をキャストといいます。
    誤解を招くので、この言い方は訂正すべき。キャストはある型を別の型として扱うことであり、Stringへの変換はここではキャストと関係ありません。

    キャンセル

  • 2017/01/06 12:05

    ご指摘ありがとうございます。言われてから気づきました。この場合、「文字列と連結」という言葉を使うべきでした。型変換では意味合いが変わってしまいますね。

    キャンセル

  • 2017/01/06 12:23

    とても丁寧でわかりやすい回答ありがとうございました。
    まだまだjavaについての知識が浅いことを痛感できました。
    ご指摘いただいた箇所を修正した結果、実行例通りに表示することができました。
    ありがとうございました。

    キャンセル

0

MyFactoryクラスとFactoryViewerクラスはインターフェースクラスとか抽象クラスを継承していますか。
もし継承しているのであれば継承元のクラスを引数の型にすることでインターフェースないし、抽象クラスを利用することができます。
ポリモーフィズムで検索するとくらしいことがわかると思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • Java

    14396questions

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