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

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

ただいまの
回答率

90.51%

  • JavaScript

    16358questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6679questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • HTML5

    4003questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • CSS3

    2058questions

    CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

  • TypeScript

    341questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

このコード上でのインターフェースの価値を教えてください(>_<)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 262
退会済みユーザー

退会済みユーザー

インターフェースをまだうまく理解できてません。
このコードはとある参考書のコードなのですが、まずインターフェースを消してインターフェースを実装しなくても全く同じ結果が得られます。
それと、フィールドの宣言(?)

firstName: string;
lastName: string;
age: number;

のところも、インターフェースを実装したことにより例えば

firstName: "太郎";

みたいに書けるのかなと思ったらエラーが出て…。
ここでインターフェースに用意された型の宣言と全く同じ内容を書く意味もよく分からずで…。

interface Member{
    firstName: string;
    lastName: string;
    age: number;
    getMemberFullName():string;
}

class NormalMember implements Member{

    firstName: string;
    lastName: string;
    age: number;

    constructor(catchFN: string,catchLN: string,catchA: number){
        this.firstName = catchFN;
        this.lastName = catchLN;
        this.age = catchA;
    }

    getMemberFullName(): string{
        return this.firstName + "・" + this.lastName + "さん";
    }
}

let jane = new NormalMember("ジェーン","オールマン",18);

console.log(jane.firstName);

let resultStr = "";
resultStr = jane.getMemberFullName();

document.body.innerHTML = resultStr;

追記
firstName:"太郎";にして
this.firstName=catchFNを消すとエラーは消えるのですが、
jane.firstNameがundefinedになってしまいます…
なぜでしょうか…(T_T)

追記
これは単純になぜか書き方をミスってしまってました。
firstName = "太郎";
だとできました。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

ご提示のコードですが、ご提示のコードどおりであれば動くのではないでしょうか?大変綺麗なコードだと思います。
これをどういう風に活用すればよいか分からないということが質問の主題でしょうか?

インターフェースは大激論になりやすいテーマですが、過去の同様の質問に対して様々な視点からの回答があり、一つぐらいはしっくり来るものがあるのではないかと思いますので是非読んでみて下さい。

私のインターフェースの理解は「誰かが自分でない他の人」に対して「コードを書くこと依頼する」ときに「最低限必要な部品を強制的に実装させる」ためのものです。
(なので1人で教本を読んでいてもその意図が良く分からないのはとても自然なことです)

友人のAさんにoguramk5さんがコードの実装をお願いするときに、「必要な部品はfirstNameというプロパティとlastNameというプロパティと・・getMemberFullNameというメソッドです。覚えてね」という風にお願いするのか、「必要な部品はMemberインターフェースにまとめておいたからそれを実装してね」とお願いするのかということです。

実装完了後、前者の場合、指定どおりに実装されているのかは内容をチェックする必要がありますが(例えばfirstNameがきちんとstring型で宣言されているかどうか等)、後者の場合は事前に定義しておいたインターフェースの通りに実装しなければエラーになりますので、実装完了後に内容をチェックする負荷がある程度軽減されます。
上記のどちらが良いということではなくて、そういうことをするための考え方がインターフェースです。

現状でエラーが出ているようですが、それは参考書の意図した通りにインターフェースの実装ができていないためです。(そのようにoguramk5さんが変更してしまった?)
「誰かの作ったインターフェースの意図どおりに作らないとエラーになってしまう」という面倒なことをわざわざさせるためのものがインターフェースです。
そうして完成したコードは、「インターフェースの作者」から見ると都合の良いコードになっているはずですが、「実装者」から見ると実装が制限されているため自由度を奪われていますので、あまり気持ちの良いものではないはずです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/12 14:23

    私のインターフェースの理解は「誰かが自分でない他の人」に対して「コードを書くこと依頼する」ときに「最低限必要な部品を強制的に実装させる」
    というのはすごい分かりやすいです、ありがとうございます。
    だから一つでも使わない型?があるとエラーになってしまうのですね。

    このコードでエラーは出ません。
    フィールド
    firstName: string;
    lastName: string;
    age: number;

    のところでfirtstName:"太郎";にするとエラー出ます。
    普通にthis.firstName=catchFNに太郎が上書きされるだけだと思っていたのですが…。
    てこれは、正しくは
    firtstName="太郎";
    にすればよくて、書き方を間違えているだけでした。

    キャンセル

  • 2017/12/12 14:42 編集

    >だから一つでも使わない型?があるとエラーになってしまうのですね。
    そういうことです。教本がmemberインターフェースを定義した通りに実装しないとエラーになるのです。

    余談ですが、

    let jane = new NormalMember("ジェーン","オールマン",18);



    let taro = new NormalMember("太郎","佐藤",22);

    のようにするのがオブジェクト指向的なコードの設計になるのですが、その件はこの主題から外れてしまいますのであまり言及しないことにします。

    キャンセル

  • 2017/12/12 15:17 編集

    ぼくはインターフェースを実装するということは、そこにある型をそのまま使えるということなんじゃないかと思ってて。むしろそうじゃないと意味がないと何故か思ってしまっていて。笑
    例えば、クラスの最初の方で

    firstName: string;
    lastName: string;
    age: number;

    って宣言しなくても

    constructor(catchFN: string,catchLN: string,catchA: number){
    this.firstName = catchFN;
    this.lastName = catchLN;
    this.age = catchA;
    }

    と書けないとインターフェースを実装した意味がないと思ってて
    実装っていう日本語的にも、そんな風な感じで型を受け継いで既に使えるようになるみたいな…。
    でもそれってそもそもそこまで意味がない気もしてくるし、
    「最低限必要な部品を強制的に実装させる」ように
    強制的に宣言させるためというか、それだったらそういう意味はあるなと思ってとても納得しました。
    日本語が変ですみません。

    let jane = new NormalMember("ジェーン","オールマン",18);

    let taro = new NormalMember("太郎","佐藤",22);

    では何が違うんでしょうか

    キャンセル

  • 2017/12/12 15:32 編集

    でもぼくがそうゆう風に混乱してしまったのは

    interface Member{
    firstName: string;
    lastName: string;
    age: number;
    }

    let mike: Member = {
    firstName:"マイケル",
    lastName:"シンクレア",
    age: 25
    };

    みたいな書き方はできるからだと思います。
    ちょっと考えれば考えるほどわからなくなってきました。

    この場合は

    let mike: Member = {

    firstName: string;
    lastName: string;
    age: number;

    firstName:"マイケル",
    lastName:"シンクレア",
    age: 25
    };

    とする必要はないんですよね。
    クラスと変数で違うのがなんかしっくり来ないのかもしれません。

    キャンセル

  • 2017/12/12 15:43 編集

    >ぼくはインターフェースを実装するということは、そこにある型をそのまま使えるということなんじゃないかと思ってて。むしろそうじゃないと意味がないと何故か思ってしまっていて。笑

    実はそういうものもあります。それは名前が違い、「継承」と言います。参考→https://docs.solab.jp/typescript/class/inheritance/
    もしかするとその教本の中にも出てくるかもしれません。
    継承とかインターフェースとか、これは「オブジェクト指向」という考え方によるものでして、理解するのは大変ですが、昨今のプログラミング言語の基本設計の至る所に採用されている概念ですので、勉強することでプログラミング言語の習得に非常に役立ちます。是非勉強してみて下さい。

    >let jane = new NormalMember("ジェーン","オールマン",18);
    >と
    >let taro = new NormalMember("太郎","佐藤",22);
    >では何が違うんでしょうか

    これもオブジェクト指向的な考え方が必要でして、その考え方が理解できていないとこのコードの意味が全く分からないのですが、
    クラスと呼ばれる「設計図」を用意して、必要に応じて「設計図を元に実体を作る」ということがオブジェクト指向では重要な概念となります。

    最初に提示されているコードにおける、「NormalMember」がクラスです。(class NormalMemberと書いてありますね)
    クラスは設計図で、「NormalMember」の実体を産み出すためのものです。
    new NormalMember(【名前】,【名字】,【年齢】)とすることで、名前、名字、年齢を持った実体であるメンバーを作り出すことができます。

    let jane = new NormalMember("ジェーン","オールマン",18);
    とすると実体janeが生成できます。

    let taro = new NormalMember("太郎","佐藤",22);
    とすると実体taroが生成できます。

    jane.getMemberFullName()とすると「ジェーン・オールマンさん」、taro.getMemberFullName()とすると「太郎・佐藤さん」と表示されるはずです。
    これの何が良いかという議論は初学の方にはとても難しいのでひとまず割愛しますが、

    >みたいな書き方はできるからだと思います。
    >クラスと変数で違うのがなんかしっくり来ないのかもしれません。

    こういった疑問に答え得る話です。
    極端に言ってしまうとそのように書くとクラスの役割を果たすことができませんので全く意味のないコードになっています。(そもそもclassで宣言せずletで宣言されていますが)

    クラスが果たすべき役割、クラスとは設計図であるということがきちんと理解できれば、今抱えている上記のような疑問は無くなると思います。

    キャンセル

  • 2017/12/12 15:56

    継承とかsuperみたいなのはやりました。なるほどです。

    janeとtaroで違いがあるのかと勘違いしていました。
    そういうことですね。
    引数に応じて、骨組みを残しつつ異なった内容を出力できるんですよね。
    この場合だとコンストラクターに入る値を変えて、異なった値でオブエクトを作るといったところでしょうかね。

    当初の質問であったクラスに対するインターフェースの意味に関して、けっこう理解できた気がします。
    ありがとうございました。

    キャンセル

  • 2017/12/12 16:08 編集

    >この場合だとコンストラクターに入る値を変えて、異なった値でオブエクトを作るといったところでしょうかね。
    ほぼ理解されていますね。少し説明を加えておきましょう。

    コンストラクタというのはクラス内の「オブジェクト生成装置」です。「オブジェクト生成装置」が無いとクラスはオブジェクトを生成できませんのでクラス内に必ず一つコンストラクタが必要です。

    概念的な話は上記ですが、プログラミングにおけるコンストラクタは、クラスという設計図からオブジェクトを生成するときに「初期値を設定する」役割を担うことが殆どであると理解しておくと良いと思います。

    今回のケースで言えば、janeの場合はNormalMemberの値の初期値として「firstNameにジェーン、lastNameにオールマン、ageに18」を設定するのがコンストラクタの役割です。
    そうして初期値を設定しておけば、jane.getMemberFullName()としたときに設定しておいた初期値を使って内部で文言を組み立てて出力してくれます。

    キャンセル

+2

1つのクラスしかない場合、interfaceを使うメリットは特にありません。

一方で、NormalMember以外にMemberを用意することになった場合、SpecialMember implements Memberとして、getMemberFullNameを実装しなければコンパイルエラーになります。

Memberを使う側にしても、「中身はどんな型かわからないけど、interfaceにあるメンバーはすべて使える」前提でコードを書けるので、実際のコードとの依存関係を減らすことができます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/12 12:40

    「Memberを使う側にしても、「中身はどんな型かわからないけど、interfaceにあるメンバーはすべて使える」前提でコードを書けるので、実際のコードとの依存関係を減らすことができます。」これはgetMemberFullNameに関しておっしゃてますか

    キャンセル

  • 2017/12/12 12:45

    あと実際のコードとの依存関係というところも少し難しいです、どういうことでしょうか(>_<)すみません…

    キャンセル

  • 2017/12/12 13:32

    「実際のコードとの依存関係」ということですが、たとえば「特殊なMemberクラスを作る」工程と「Memberの配列をHTMLテーブルに展開する」工程を別の人が担当することになった場合に、interfaceに則ったものを作れば、テーブルを作成する側でどんなMemberが来るか気にしなくても良くなるし、逆に特殊なMemberクラスを作る側でも使い方を気にしなくて良くなる、という感じです。

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • JavaScript

    16358questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6679questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • HTML5

    4003questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • CSS3

    2058questions

    CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

  • TypeScript

    341questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。