interface+自作 (八週目の学習)

<font color="limegreen">モチベーションも大事だと思うので覚書として使用します。</font>
<font color="DarkSlateGray"><details><summary>八週目の感想</summary><div>今週はinterfaceとコード作りました。
一度作ればその定義でいくらでも共通化や変更できるので大変便利だと思いました。


また、ご指導頂いた事もあり、実際の計算に理解がない学習は、効率悪いし
テスト勉強のような学習になってしまっていたので注意が必要と思いました。
一応終わらせたいので一気にしてから、毎週自力で作りたいです。
できればスマホで動く所まで。パーツ以外は自動化？できるんじゃないかと思いました。

とにかく、10週まで一気に終わらせて、メインで自作練習していこうと思いました。

今週、前半は今後の方針を考えて後半はコードを考えてました。単純に自分で考えるのは楽しい。
その際、調べすぎるとコピペ上手くなるだけになりそうなので注意したい。
恥を忍んで初心者全開で始める方が、背伸びしてコピペするより学習になるはず。
最初に自分で作った型表、仕様を確認する位で基本考えながら作りたいなと。
(そして色々ご指摘頂けたらいいなぁと…でも何も反応ない記事も多々ありその方が恐怖)



あとスマホの実装が具体的に気になって、ｸﾗｲｱﾝﾄやﾊﾞｯｸｴﾝﾄﾞ等の設計手順とか
DevOps調べてたらはまって若干焦りました。
この調子で2年でリリース可能なのか…まずやる事を整理しました。
複数選択肢作ったけど、全部並行して進めようと思います。

1.一気に学習終わらせる
2.ついでに学習項目使って自作
3.終わらせたら今後メインで自作しまくる(鍛える)
4.並行でXamarin/DevOps(モバイルアプリ設計手順)学習
5.並行でモック・プロトタイプ・クローンアプリ?(説明用)
6.並行で事業計画書等の資料製作(説明用)
</font></details></div>








　　　　　　　　　　　　　　<img src = https://goo.gl/35nAhK width = 300 ％>


#<font color="YellowGreen">自作してみた(interface使った何か)
XamarinのOS間共有コード作ってみたかったけど、
API実装はまだ分からないので出来る範囲で作って画面に出しました。
数個のクラスでコンソールに表示しただけです。
具体的にはユーザの入力に対し☆印で出力するようなもので、恐らく`case`で書けるかなと。
イメージはできたけど書き方忘れて前記事見ながら、動けばいいという心境になり暗中模索…

```c#:InterReview
using System;



public interface IReview
{
    void Review(int r);
}




class IOS1 : IReview
{
    public void Review(int r)
    {
        var IReview = new star();
    }
}



class star
{
    static void Main()
    {
        Console.WriteLine("評価を入力してください(5段階)");
        int star = int.Parse(Console.ReadLine());
        
        switch (star)
        {
            case 0:
                Console.WriteLine("☆☆☆☆☆");
                break;
            case 1:
                Console.WriteLine("★☆☆☆☆");
                break;
            case 2:
                Console.WriteLine("★★☆☆☆");
                break;
            case 3:
                Console.WriteLine("★★★☆☆");
                break;
            case 4:
                Console.WriteLine("★★★★☆");
                break;
            case 5:
                Console.WriteLine("★★★★★");
                break;
            default:
                Console.WriteLine("error");
                break;
                
        }
    }
}

```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/252588/3ca2450d-30d4-3df0-dca1-c0fba7473ed0.png)

<br>

━━━━━━━━━━━━━━━━━以上。以下`interface`仕様━━━━━━━━━━━━━━━━━

<br>
#<font color="SlateGray">インターフェイス interface
`interface`は、異なる言語や機能間の共通コードを作成し共通化できます。
使用にはpublic `interface 名前{抽象メンバ}`とします。
<details><summary>基本的なコード例をここに示します</summary><div>


```c#
namespace Phoneword
{
    public interface IDialer//インターフェイス定義
    {
        bool Dial(string number);//インターフェイス定義
    }
}

```
</details></div>

※使用する場合、習慣的に先頭にIがつきます。(IDialer…etc)

実装には、実装したいクラスの横に`: interface名`とします。また、複数実装可能です。
`class class名: interface1, interface2, ...`
例えば[前の学習](https://qiita.com/h_okabe/items/c1a366bdb36678c72699)で、Xamarinの共通プロジェクトIDialer.csとAndroid・iOS両プロジェクト(PhoneDialer.cs)間の共通コードを作成しました。`interface`用にCSファイル作成して定義しているのでプロジェクト間の共通コードといえると思います。

```c#:Phoneword.Android.IDialer.cs
namespace Phoneword//共通なので上階層
{
    public interface IDialer//インターフェイス定義
    {
        bool Dial(string number);//インターフェイス定義
    }
}
```
定義した`interface`を、`Phoneword.Android.PhoneDialer.cs` `Phoneword.iOS.PhoneDialer.cs`にそれぞれ実装していきます。
実装するthrow new～のような文は、

ちなみにこのアプリはテキストから電話番号に変換するアプリなので、interfaceの定義bool型 Dialは
null(ありえない番号)でFalse、TrueでMONOというAndroidのAPIに移項し処理されます。
一方iOSはTrue、False共にUIKitというiOSのAPIに移項し処理されます。

```c#:Phoneword.Android.PhoneDialer.cs
using Android.Content;
using Android.Telephony;
using Phoneword.Droid;
using System.Linq;
using Xamarin.Forms;
using Uri = Android.Net.Uri;

[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.Droid
{
    public class PhoneDialer : IDialer// interfaceでIDialer実装(習慣的に先頭Iで始まる)
    {
        public bool Dial(string number)// interface(抽象メンバ)なのでそれぞれ定義した
        {
            var context = MainActivity.Instance;
            if (context == null)
                return false;

            var intent = new Intent(Intent.ActionDial);
            intent.SetData(Uri.Parse("tel:" + number));

            if (IsIntentAvailable(context, intent))
            {
                context.StartActivity(intent);
                return true;
            }

            return false;
        }

        public static bool IsIntentAvailable(Context context, Intent intent)
        {
            var packageManager = context.PackageManager;

            var list = packageManager.QueryIntentServices(intent, 0)
                .Union(packageManager.QueryIntentActivities(intent, 0));

            if (list.Any())
                return true;

            var manager = TelephonyManager.FromContext(context);
            return manager.PhoneType != PhoneType.None;
        }
    }
}
```
<br>

```c#:Phoneword.iOS.IDialer.cs
using Foundation;
using Phoneword.iOS;
using UIKit;
using Xamarin.Forms;

[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.iOS
{
    public class PhoneDialer : IDialer// interfaceでIDialer実装(習慣的に先頭Iで始まる)
    {
        public bool Dial(string number)// interface(抽象メンバ)なのでそれぞれ定義した
        {
            return UIApplication.SharedApplication.OpenUrl(new NSUrl("tel:" + umber));
        }
    }
}
```

<font color="crimson">このように、newインスタンス作る事で実装されまています(右クリの自動実装はとりあえずの空の実装 `throw new NotImplementedException();` )

</font>

<font color="Silver">memo:
共通定義できるインターフェイス(定義)(抽象メンバのみ)
多重定義できるオーバーロード(読み込み)(引数違う)
再定義できるオーバーライド(上書き)(引数同じメソッド)</font>





###<font color="DimGray">インターフェイスの継承</font>
`interface`の継承は、ｸﾗｽの継承と同じでｲﾝﾀｰﾌｪｲｽｸﾗｽを継承する事ができます。

使用には、`interface 名前 : 継承したいインターフェイス名`とします。


<details><summary>基本的なコード例をここに示します</summary><div>

```c#
// C# program to illustrate the interface 
using System; 
  
// interface declaration 
interface Vehicle { 
      
    // all are the abstract methods. 
    void changeGear(int a); 
    void speedUp(int a); 
    void applyBrakes(int a); 
} 
  
// class implements interface 
class Bicycle : Vehicle{ 
      
    int speed; 
    int gear; 
      
    // to change gear 
    public void changeGear(int newGear) 
    { 
          
        gear = newGear; 
    } 
      
    // to increase speed 
    public void speedUp(int increment) 
    { 
          
        speed = speed + increment; 
    } 
      
    // to decrease speed 
    public void applyBrakes(int decrement) 
    { 
          
        speed = speed - decrement; 
    } 
      
    public void printStates()  
    { 
        Console.WriteLine("speed: " + speed +  
                          " gear: " + gear); 
    } 
} 
  
// class implements interface 
class Bike : Vehicle { 
      
    int speed; 
    int gear; 
      
    // to change gear 
    public void changeGear(int newGear) 
    { 
          
        gear = newGear; 
    } 
      
    // to increase speed 
    public void speedUp(int increment) 
    { 
          
        speed = speed + increment; 
    } 
      
    // to decrease speed 
    public void applyBrakes(int decrement){ 
          
        speed = speed - decrement; 
    } 
      
    public void printStates()  
    { 
        Console.WriteLine("speed: " + speed +  
                          " gear: " + gear); 
    } 
      
} 
  
class GFG { 
      
    // Main Method 
    public static void Main(String []args)  
    { 
      
        // creating an instance of Bicycle  
        // doing some operations  
        Bicycle bicycle = new Bicycle(); 
        bicycle.changeGear(2); 
        bicycle.speedUp(3); 
        bicycle.applyBrakes(1); 
          
        Console.WriteLine("Bicycle present state :"); 
        bicycle.printStates(); 
          
        // creating instance of bike. 
        Bike bike = new Bike(); 
        bike.changeGear(1); 
        bike.speedUp(4); 
        bike.applyBrakes(3); 
          
        Console.WriteLine("Bike present state :"); 
        bike.printStates(); 
    } 
} 


```

Output:
`Bicycle present state :
speed: 2 gear: 2
Bike present state :
speed: 1 gear: 1`
</details></div>

<font color="crimson">このように、多重継承と抽象化を実現できました</font>