C . Chornの擬態語


インターフェースはもうインターフェースではない



デフォルトの実装とのインターフェイスの素晴らしく恐ろしい考えを持つC .
まず第一に、デフォルト実装のインターフェースがひどい考えであると言うことから始めたいです.インタフェースは実装の契約の無効であり、デフォルトの実装を行う場所がない.これはインターフェイスの全体の目的を破ります.おそらく、抽象クラスの複数の継承の手当に良いかもしれません.しかし、私は消化します.

特徴



デフォルト実装のインタフェースの背後にあるアイデアはすべて、特徴として知られているプログラミング概念から来ます.特徴としては、デフォルトの振る舞いをオブジェクトにアタッチすることができます.
あなたはRunnerSwimmerFlyerのような特徴を持つことができました.
  • RunnerRunning() { ... }のための実装をするでしょう
  • SwimmerSwimming() { ... }
  • のための実施をするでしょう
  • FlyerFlying() { ... }のための実装で来るでしょう.
  • 現在、PenguinRunnerの両方を使用してSwimmerSwimming()の両方を使用してRunning()Swiftを定義することができました.
    Cは本当にこれを行うために開発されていない、または少なくともこれを行うには.特徴は、より機能的な構成です.Protocol-Oriented Programmingのような言語は、Protocol Extensionsスタイルで、Swiftと非常にうまくこの概念に応えます.
    C ' z ' 7.0で創造的な方法を見てみましょう.私は非常に緩やかに創造的な用語を使用します.

    ゲットウィティ


    Protocolにおいては、24579142はC≧のInterfaceと非常によく似ており、Protocol Extensionを通して特性の能力を達成する.SwiftのProtocol Extensionは、理論的にはC . C .で242479142の拡張子に似ています.これは、私がC - Countに特徴を成し遂げる方法を見つけようとするように私を奮起させました.
    形を作りましょう.
  • 形は、
  • を転がすことができます
  • といくつかの形がバウンスすることができます.
  • いくつかの図形は、両方のロールとバウンスすることができます.
  • これを実装するオブジェクト指向の方法は、ローリングとバウンスのインターフェイスを作成することです.
    ロールする任意の形状はInterfaceインターフェイスを実装する必要があります、任意の形状バウンスは、rollingインターフェイスを実装する必要があります.おそらく、圧延と跳ねることは、各々の形のためにそれほど異なりませんでしたか?バウンスはバウンスとロールはロールです.そして、多分我々は行って、我々がつくるあらゆる一つの形のために弾みまたはロールを実行したくありません.
    しかし、待って、なぜ、ちょうどロールバックbouncingを作成しないと言うかもしれない?またはsuper classは、バウンス?
    第一に、継承は悪い.第二に、ロール、スーパークラスをロールバックし、バウンススーパークラスを作成するつもりですか?MMM、あなたが複数の遺産を持っているならば..
    複数の継承をクラスで持っていませんが、複数のインターフェイスを実装できます.
    …今何をしますか.私はインターフェイスの拡張子にヒントを、私はそれがどのように動作するかを説明しましょう.
  • 免責事項:これはコードを書くの良い方法として推奨されていない、それは厳密に思考実験です.
  • クックゲット



    いくつかの特性をボイラープレートにしましょう.
    public abstract class Trait { }
    
    interface ITrait<T> where T : Trait { }
    
    我々は、我々の特徴のためのフィルタであるために、抽象クラスsuper classを持ちます.我々は直接Traitを実装したくないが、我々は確かに特性であるものの家族をしたいです.インターフェースを定義するとき、形質クラスは使用されます.
    インターフェイスを使用するキーは、我々はそれらの複数を実装することができますので、我々は我々が望むように多くの特徴を持つことができます.
    次に、いくつかの特徴を作成しましょう.
    public CanRoll : Trait { }
    
    public CanBounce: Trait { }
    
    また、これはボイラープレートの一種です.それは私たちが魔法の特徴を実装できるようになる綿毛のビットです.
    最後に、ジュースになる.
    public static class ShapeTraits
    {
        // this only applies to objects that CanBounce
        public static void Bounce(this ITrait<CanBounce> bouncer)
        {
            Console.WriteLine("I can bounce!");
        }
    
        // this only applies to objects that CanRoll
        public static void Roll(this ITrait<CanRoll> roller)
        {
            Console.WriteLine("I can roll!");
        }
    }
    
    そこに-私たちの2つの美しい特徴を実装.次に、いくつかの図形を作成してみましょう.
    // A cylinder can roll
    public class Cylinder: ITrait<CanRoll>
    {
        // this is empty!
    }
    
    // A cube can bounce
    public class Cube: ITrait<CanBounce>
    {
        // this is empty!
    }
    
    // And, implementing multiple interfaces,
    // a ball can bounce and roll!
    public class Ball: ITrait<CanBounce>, ITrait<CanRoll>
    {
        // this is empty!
    }
    
    今、我々はこれらのクラスのインスタンスを作成することができます、クラスは全くコードを含んでいません、そして、これらの擬似特徴のため、彼らは実際に物事をすることができます!
    var cylinder = new Cylinder();
    cylinder.Roll(); // this works!
    
    var cube = new Cube();
    cube.Bounce(); // this works!
    
    var ball = new Ball();
    // a ball that rolls and bounces
    ball.Roll();
    ball.Bounce(); 
    

    インターフェイスの拡張子を使用して、我々は、私は偽の特徴を呼び出す何かを作成するために、特性の能力を模倣するために管理している.それはオブジェクトについての異なる考え方です、そして、私は私が本当にそれが好きであると言わなければなりません.
    あなたは拡張メソッドを構築することができますし、手は、特定の特性に属するものを選択します.オブジェクトに対してどの特性を選ぶかによって、正しいインターフェイスを実装するだけで、オブジェクトをビット単位で構築することができます.
    これはいい考えですか.正直、私は知りません.楽しい思考実験ですか?確かにそう思う.