Upgrade to Pro — share decks privately, control downloads, hide ads and more …

仮想関数テーブルと型クラスを見比べる

INA Lintaro
January 26, 2024

 仮想関数テーブルと型クラスを見比べる

型クラスについての理解を深めるために、仮想関数テーブルで部分型多相+動的ディスパッチを実現した場合との違い・共通点を見比べてみます。型クラスは(その出自はともかく)関数型プログラミング特有の概念というわけではないことを確かめます。

INA Lintaro

January 26, 2024
Tweet

More Decks by INA Lintaro

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ ໊લ ɹ ͍ ͳ ҏಸ ɹ ɹ ΓΜͨΖ͏ ྛଠ࿠

    ɹ ( id:tarao @tarao @oarat) 2021-02 ∼ ͸ͯͳ ΤϯδχΞϦϯάϚωʔδϟ 2013-04 ∼ ͸ͯͳ ΤϯδχΞ 2010-04 ∼ ژ౎େֶ ৘ใֶݚڀՊ (ࠤ౻ɾޒेཛྷݚ) ത࢜ޙظ՝ఔ / ೔ຊֶज़ৼڵձ ಛผݚڀһ (DC1) ࠷ۙ ▶ record4s: extensible records for Scala ▶ ͋ΒΏΔϓϩάϥϛϯάݴޠͷ࠷ઌ୺Λߦ ͘ Scala 3 ͷϚΫϩ ੲ ▶ L. Ina and A. Igarashi. Gradual Typing for Generics. In Proc. of OOPSLA 2011. ▶ “gradual typing” Λʮ઴ਐతܕ෇͚ʯͱ༁ ͨ͠ऀͷ 1 ਓ
  2. ܕΫϥεͱOOP SPJ ᐌ͘ “ ▶ A bit like OOP, except

    that method suite passed separately? ▶ No!! Type classes implement type-based dispatch, not value-based dispatch ▶ S. P. Jones. Classes, Jim, but not as we know them — Type classes in Haskell. In ECOOP 2009.
  3. ݴޠػೳͷҙຯ࿦ ݴޠ L ͷػೳ F ▶ L ⇝ (L −

    F) ͷม׵Ͱఆٛ͢Δ (࣮ࡍͷॲཧܥʹ͓͚Δ౶ҥߏจͷ desugar ʹ૬౰) ྫ ▶ ݴޠ L : Haskell ▶ ػೳ F : ܕΫϥε ▶ ม׵ : ܕΫϥε͋Γͷ Haskell ⇝ ܕΫϥεͳ͠ͷ Haskell (Wadler ’89 ͷ࿦จͰ΋࣮ࡍͦ͏΍ͬͯҙຯ࿦Λ༩͍͑ͯΔ)
  4. OOP

  5. OOP (෦෼ܕଟ૬ + ಈతσΟεύον) abstract class Pet: def speak(): String

    class Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() listen(new Cat) // "Meow" listen(new Dog) // "Woof"
  6. OOP (෦෼ܕଟ૬ + ಈతσΟεύον) abstract class Pet: def speak(): String

    class Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() listen(new Cat) // "Meow" listen(new Dog) // "Woof" ▶ ҟͳΔܕΛ౷Ұతʹѻ͍͍ͨ
  7. OOP (෦෼ܕଟ૬ + ಈతσΟεύον) abstract class Pet: def speak(): String

    class Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() listen(new Cat) // "Meow" listen(new Dog) // "Woof" ▶ ڞ௨ͷ্ҐܕΛࢦఆ (෦෼ܕଟ૬)
  8. OOP (෦෼ܕଟ૬ + ಈతσΟεύον) abstract class Pet: def speak(): String

    class Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() listen(new Cat) // "Meow" listen(new Dog) // "Woof" ▶ ಉ໊ϝιουΛ෦෼ܕ͝ͱʹ࣮૷
  9. OOP (෦෼ܕଟ૬ + ಈతσΟεύον) abstract class Pet: def speak(): String

    class Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() listen(new Cat) // "Meow" listen(new Dog) // "Woof" ▶ ݺ͹ΕΔͷ͸෦෼ܕͷϝιου࣮૷ (ಈతσΟεύον)
  10. OOPͷҙຯ࿦ (Ծ૝ؔ਺ςʔϒϧ (vtable)) abstract class Pet: def speak(): String class

    Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() abstract class Pet( val vtable: PetMethods ) class PetMethods(val speak: Pet => String) class Cat extends Pet( CatIsPet ): def speak(): String = "Meow" val CatIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Cat].speak() ) class Dog extends Pet( DogIsPet ): def speak(): String = "Woof" val DogIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Dog].speak() ) def listen(pet: Pet): String = pet.vtable .speak(pet) ˞ ࣮ࡍͷॲཧܥͷ࣮૷ͱ͸ҟͳΔ (͋͘·Ͱ֓೦্ͷઆ໌)
  11. OOPͷҙຯ࿦ (Ծ૝ؔ਺ςʔϒϧ (vtable)) abstract class Pet: def speak(): String class

    Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() abstract class Pet( val vtable: PetMethods ) class PetMethods(val speak: Pet => String) class Cat extends Pet( CatIsPet ): def speak(): String = "Meow" val CatIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Cat].speak() ) class Dog extends Pet( DogIsPet ): def speak(): String = "Woof" val DogIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Dog].speak() ) def listen(pet: Pet): String = pet.vtable .speak(pet) ▶ override ͳ͠Ͱॻ͘
  12. OOPͷҙຯ࿦ (Ծ૝ؔ਺ςʔϒϧ (vtable)) abstract class Pet: def speak(): String class

    Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() abstract class Pet( val vtable: PetMethods ) class PetMethods(val speak: Pet => String) class Cat extends Pet( CatIsPet ): def speak(): String = "Meow" val CatIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Cat].speak() ) class Dog extends Pet( DogIsPet ): def speak(): String = "Woof" val DogIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Dog].speak() ) def listen(pet: Pet): String = pet.vtable .speak(pet) ▶ ڞ௨ͷϝιουͷശ (ࣙॻ) Λ༻ҙ͓ͯ͘͠
  13. OOPͷҙຯ࿦ (Ծ૝ؔ਺ςʔϒϧ (vtable)) abstract class Pet: def speak(): String class

    Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() abstract class Pet( val vtable: PetMethods ) class PetMethods(val speak: Pet => String) class Cat extends Pet( CatIsPet ): def speak(): String = "Meow" val CatIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Cat].speak() ) class Dog extends Pet( DogIsPet ): def speak(): String = "Woof" val DogIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Dog].speak() ) def listen(pet: Pet): String = pet.vtable .speak(pet) ▶ ෦෼ܕ͝ͱʹผʑͷϝιουΛ٧Ί͓ͯ͘
  14. OOPͷҙຯ࿦ (Ծ૝ؔ਺ςʔϒϧ (vtable)) abstract class Pet: def speak(): String class

    Cat extends Pet: override def speak(): String = "Meow" class Dog extends Pet: override def speak(): String = "Woof" def listen(pet: Pet): String = pet.speak() abstract class Pet( val vtable: PetMethods ) class PetMethods(val speak: Pet => String) class Cat extends Pet( CatIsPet ): def speak(): String = "Meow" val CatIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Cat].speak() ) class Dog extends Pet( DogIsPet ): def speak(): String = "Woof" val DogIsPet = PetMethods((pet: Pet) => pet.asInstanceOf[Dog].speak() ) def listen(pet: Pet): String = pet.vtable .speak(pet) ▶ vtable Λܦ༝ͯ͠ϝιουΛݺͿ
  15. ܕΫϥε (ύϥϝʔλଟ૬ + ΞυϗοΫଟ૬) trait Pet[P] : extension (p: P)

    def speak(): String class Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet ](pet: P ): String = pet.speak() listen( new Cat ) // "Meow" listen( new Dog ) // "Woof"
  16. ܕΫϥε (ύϥϝʔλଟ૬ + ΞυϗοΫଟ૬) trait Pet[P] : extension (p: P)

    def speak(): String class Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet ](pet: P ): String = pet.speak() listen( new Cat ) // "Meow" listen( new Dog ) // "Woof" ▶ ҟͳΔܕΛ౷Ұతʹѻ͍͍ͨ
  17. ܕΫϥε (ύϥϝʔλଟ૬ + ΞυϗοΫଟ૬) trait Pet[P] : extension (p: P)

    def speak(): String class Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet ](pet: P ): String = pet.speak() listen( new Cat ) // "Meow" listen( new Dog ) // "Woof" ▶ ಛఆͷΠϯλϑΣʔεΛཁٻ (͜Ε͕ܕΫϥε)
  18. ܕΫϥε (ύϥϝʔλଟ૬ + ΞυϗοΫଟ૬) trait Pet[P] : extension (p: P)

    def speak(): String class Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet ](pet: P ): String = pet.speak() listen( new Cat ) // "Meow" listen( new Dog ) // "Woof" ▶ ΠϯλϑΣʔεΛຬͨ͢ূڌ (ܕΫϥεͷΠϯελϯε)
  19. ܕΫϥε (ύϥϝʔλଟ૬ + ΞυϗοΫଟ૬) trait Pet[P] : extension (p: P)

    def speak(): String class Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet ](pet: P ): String = pet.speak() listen( new Cat ) // "Meow" listen( new Dog ) // "Woof" ▶ ূڌʹج͍ͮͯݺͼ෼͚
  20. ܕΫϥεͷҙຯ࿦ trait Pet[P]: extension (p: P) def speak(): String class

    Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P): String = pet.speak() class Pet[P](val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat]((cat: Cat) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog]((dog: Dog) => dog.speak()) def listen[P](pet: P) (dict: Pet[P]) : String = dict .speak(pet)
  21. ܕΫϥεͷҙຯ࿦ trait Pet[P]: extension (p: P) def speak(): String class

    Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P): String = pet.speak() class Pet[P](val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat]((cat: Cat) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog]((dog: Dog) => dog.speak()) def listen[P](pet: P) (dict: Pet[P]) : String = dict .speak(pet) ▶ ܕΫϥεͷ࣮ମ͸ϝιουͷࣙॻ
  22. ܕΫϥεͷҙຯ࿦ trait Pet[P]: extension (p: P) def speak(): String class

    Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P): String = pet.speak() class Pet[P](val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat]((cat: Cat) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog]((dog: Dog) => dog.speak()) def listen[P](pet: P) (dict: Pet[P]) : String = dict .speak(pet) ▶ ΠϯλϑΣʔεͷূڌ͸ࣙॻΠϯελϯε
  23. ܕΫϥεͷҙຯ࿦ trait Pet[P]: extension (p: P) def speak(): String class

    Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P): String = pet.speak() class Pet[P](val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat]((cat: Cat) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog]((dog: Dog) => dog.speak()) def listen[P](pet: P) (dict: Pet[P]) : String = dict .speak(pet) ▶ ܕΫϥεΛ࢖͏ϝιου͸ࣙॻΛऔΔܗʹม׵
  24. ܕΫϥεͷҙຯ࿦ trait Pet[P]: extension (p: P) def speak(): String class

    Cat: def speak(): String = "Meow" given Pet[Cat] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[Dog] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P): String = pet.speak() listen(new Cat) listen(new Dog) class Pet[P](val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat]((cat: Cat) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog]((dog: Dog) => dog.speak()) def listen[P](pet: P) (dict: Pet[P]) : String = dict .speak(pet) listen(new Cat) (CatIsPet) listen(new Dog) (DogIsPet)
  25. ද૚Λݟൺ΂Δ OOP abstract class Pet : def speak(): String class

    Cat extends Pet : override def speak(): String = "Meow" class Dog extends Pet : override def speak(): String = "Woof" def listen(pet: Pet ): String = pet.speak() ܕΫϥε trait Pet[ P ]: extension (p: P ) def speak(): String class Cat: def speak(): String = "Meow" given Pet[ Cat ] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[ Dog ] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P ): String = pet.speak()
  26. ද૚Λݟൺ΂Δ OOP abstract class Pet : def speak(): String class

    Cat extends Pet : override def speak(): String = "Meow" class Dog extends Pet : override def speak(): String = "Woof" def listen(pet: Pet ): String = pet.speak() ܕΫϥε trait Pet[ P ]: extension (p: P ) def speak(): String class Cat: def speak(): String = "Meow" given Pet[ Cat ] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[ Dog ] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P ): String = pet.speak() ▶ ෦෼ܕଟ૬ vs. ύϥϝʔλଟ૬
  27. ද૚Λݟൺ΂Δ OOP abstract class Pet : def speak(): String class

    Cat extends Pet : override def speak(): String = "Meow" class Dog extends Pet : override def speak(): String = "Woof" def listen(pet: Pet ): String = pet.speak() ܕΫϥε trait Pet[ P ]: extension (p: P ) def speak(): String class Cat: def speak(): String = "Meow" given Pet[ Cat ] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[ Dog ] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P ): String = pet.speak() ▶ ؔ܎͕ܕͷఆٛͱີ݁߹ vs. ؔ܎͕ޙ෇͚
  28. ද૚Λݟൺ΂Δ OOP abstract class Pet : def speak(): String class

    Cat extends Pet : override def speak(): String = "Meow" class Dog extends Pet : override def speak(): String = "Woof" def listen(pet: Pet ): String = pet.speak() ܕΫϥε trait Pet[ P ]: extension (p: P ) def speak(): String class Cat: def speak(): String = "Meow" given Pet[ Cat ] with extension (cat: Cat) def speak(): String = cat.speak() class Dog: def speak(): String = "Woof" given Pet[ Dog ] with extension (dog: Dog) def speak(): String = dog.speak() def listen[P: Pet](pet: P ): String = pet.speak() ▶ ಉ໊ͰΦʔόʔϥΠυ vs. όϥόϥʹ࣮૷ (ผ໊Ͱ΋Մ)
  29. ҙຯ࿦Λݟൺ΂Δ OOP abstract class Pet ( val vtable: PetMethods )

    class PetMethods (val speak: Pet => String) class Cat extends Pet(CatIsPet) : def speak(): String = "Meow" val CatIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Cat] .speak()) class Dog extends Pet(DogIsPet) : def speak(): String = "Woof" val DogIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Dog] .speak()) def listen(pet: Pet ): String = pet.vtable .speak(pet) ܕΫϥε class Pet[P] (val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat] ((cat: Cat ) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog] ((dog: Dog ) => dog.speak()) def listen [P] (pet: P ) (dict: Pet[P]) : String = dict .speak(pet)
  30. ҙຯ࿦Λݟൺ΂Δ OOP abstract class Pet ( val vtable: PetMethods )

    class PetMethods (val speak: Pet => String) class Cat extends Pet(CatIsPet) : def speak(): String = "Meow" val CatIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Cat] .speak()) class Dog extends Pet(DogIsPet) : def speak(): String = "Woof" val DogIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Dog] .speak()) def listen(pet: Pet ): String = pet.vtable .speak(pet) ܕΫϥε class Pet[P] (val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat] ((cat: Cat ) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog] ((dog: Dog ) => dog.speak()) def listen [P] (pet: P ) (dict: Pet[P]) : String = dict .speak(pet) ▶ ෦෼ܕଟ૬ vs. ύϥϝʔλଟ૬
  31. ҙຯ࿦Λݟൺ΂Δ OOP abstract class Pet ( val vtable: PetMethods )

    class PetMethods (val speak: Pet => String) class Cat extends Pet(CatIsPet) : def speak(): String = "Meow" val CatIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Cat] .speak()) class Dog extends Pet(DogIsPet) : def speak(): String = "Woof" val DogIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Dog] .speak()) def listen(pet: Pet ): String = pet.vtable .speak(pet) ܕΫϥε class Pet[P] (val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat] ((cat: Cat ) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog] ((dog: Dog ) => dog.speak()) def listen [P] (pet: P ) (dict: Pet[P]) : String = dict .speak(pet) ▶ ໊લ͕ҧ͏͚ͩ
  32. ҙຯ࿦Λݟൺ΂Δ OOP abstract class Pet ( val vtable: PetMethods )

    class PetMethods (val speak: Pet => String) class Cat extends Pet(CatIsPet) : def speak(): String = "Meow" val CatIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Cat] .speak()) class Dog extends Pet(DogIsPet) : def speak(): String = "Woof" val DogIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Dog] .speak()) def listen(pet: Pet ): String = pet.vtable .speak(pet) ܕΫϥε class Pet[P] (val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat] ((cat: Cat ) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog] ((dog: Dog ) => dog.speak()) def listen [P] (pet: P ) (dict: Pet[P]) : String = dict .speak(pet) ▶ ஋͔ΒऔΓग़͢ vs. Ҿ਺Ͱ౉͢
  33. ҙຯ࿦Λݟൺ΂Δ OOP abstract class Pet ( val vtable: PetMethods )

    class PetMethods (val speak: Pet => String) class Cat extends Pet(CatIsPet) : def speak(): String = "Meow" val CatIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Cat] .speak()) class Dog extends Pet(DogIsPet) : def speak(): String = "Woof" val DogIsPet = PetMethods ((pet: Pet ) => pet .asInstanceOf[Dog] .speak()) def listen(pet: Pet ): String = pet.vtable .speak(pet) ܕΫϥε class Pet[P] (val speak: P => String) class Cat: def speak(): String = "Meow" val CatIsPet = Pet[Cat] ((cat: Cat ) => cat.speak()) class Dog: def speak(): String = "Woof" val DogIsPet = Pet[Dog] ((dog: Dog ) => dog.speak()) def listen [P] (pet: P ) (dict: Pet[P]) : String = dict .speak(pet) ▶ ͋ͱ͸ಉ͡!!
  34. ҧ͏ͱ͜Ζ OOP ܕΫϥε ଟ૬ ෦෼ܕଟ૬ ύϥϝʔλଟ૬ ܕͷؔ܎ ີ݁߹ ޙ෇͚Մ ˞

    ϝιου࣮૷ ಉ໊ͰΦʔόʔϥΠυ ໌ࣔతʹࢦఆ ࣙॻͷ౉͠ํ ஋ʹೖΕΔ Ҿ਺Ͱ౉͢ ࣙॻͷղܾ ಈత ੩త ˞ ͜ͷͨΊʹܕΫϥεͷΠϯελϯεղܾͷ࢓૊Έ͕ඞཁ ▶ ࿦ཧܕϓϩάϥϛϯάΈ͍ͨʹͳΔ