スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

VBオブジェクト指向プログラミング講座 第15回 継承の原理を覚えよう

 この記事は、第14回 型の概念を覚えよう の続きです。前回は型について解説しました。今回は、継承について解説します。
 オブジェクト指向プログラミングをしていて避けられないのは継承です。継承なくして、オブジェクト指向プログラミングは語れません。しかしながら、継承ほど難しいオブジェクト指向の概念もないと思います。そこで今回は、継承の原理について軽く解説します。
 前回と同じくVBコンパイラがやっている事を表現してみました。

Imports System
Imports System.Collections.Generic

'型に関する情報
Friend Structure TypeInfo

    '型名。
    Public Name As String

    '型が持っている関数テーブル。
    Private table As Dictionary(Of String, Object)

    '名前を指定してインスタンスを生成する。
    Public Sub New(ByVal name As String)
        Me.Name = name
        Me.table = New Dictionary(Of String, Object)()
    End Sub

    '関数もしくは手続きを登録。
    Public Sub ResistFunctionOrSub(ByVal name As String, funcOrSub As Object)
        Me.table.Add(name, funcOrSub)
    End Sub

    '関数もしくは手続きを取得。
    Public Function GetFunctionOrSub(ByVal callName As String, ByRef func As Object) As Boolean
        Dim success As Boolean = Me.table.TryGetValue(callName, func)
        Return success
    End Function

End Structure

'オブジェクトに関する情報を表わすオブジェクト
Friend Structure ObjectInfo

    '親に関する情報
    Public ParentInfo As TypeInfo

    '型に関する情報。
    Public Info As TypeInfo

    '関数もしくは手続きを取得。
    Public Function GetFunctionOrSub(ByVal callName As String) As Object

        '自身を調べる
        Dim result As Object = Nothing
        Dim success As Boolean = Info.GetFunctionOrSub(callName, result)
        If success Then
            Console.WriteLine(callName & "は自身が持っています。")
            Return result
        End If

        'なければ親を調べる
        success = ParentInfo.GetFunctionOrSub(callName, result)
        If success Then
            Console.WriteLine(callName & "は親が持っています。")
            Return result
        End If
        Throw New ArgumentException(callName & "は存在しません。")

    End Function

End Structure

'サンプルで使用するオブジェクト
Friend Class Foo
    Public Value As Integer
End Class

Friend Class FooFoo
    Inherits Foo
End Class

'エントリポイント(プログラムの開始地点)
Module Sample

    'Foo型に関する情報を取得する。
    Function GetFooTypeInfo() As TypeInfo

        '関数のテーブルを用意
        Console.WriteLine("Foo型の準備をします。")
        Dim result As TypeInfo = New TypeInfo("Foo")

        Dim ctor As Func(Of Foo) = Function() New Foo()
        result.ResistFunctionOrSub("New", CObj(ctor))
        Console.WriteLine("コンストラクタを登録しました。")

        Dim getValue As Func(Of Foo, Integer) =
            Function(obj As Foo) obj.Value
        result.ResistFunctionOrSub("Get_Value", getValue)
        Console.WriteLine("Valueプロパティのゲッターを登録しました。")

        Dim addFunc As Func(Of Foo, Integer, Foo) =
            Function(obj As Foo, value As Integer)
                    obj.Value += value
                    Return obj
                End Function
        result.ResistFunctionOrSub("Add", addFunc)
        Console.WriteLine("Addメソッドを登録しました。")
        Console.WriteLine("Foo型の準備が終わりました。")
        Console.WriteLine()

        Return result

    End Function

    'FooFoo型に関する情報を取得する。
    Function GetFooFooObjectInfo() As ObjectInfo

        '親を用意
        Console.WriteLine("親オブジェクトの設定をします。")
        Dim parent As TypeInfo = GetFooTypeInfo()

        'FooFoo型を用意
        Console.WriteLine("FooFoo型の準備をします。")
        Dim result As ObjectInfo = New ObjectInfo()
        Dim type As TypeInfo = New TypeInfo("FooFoo")
        result.ParentInfo = parent
        result.Info = type
        Dim ctor As Func(Of FooFoo) = Function() New FooFoo()
        type.ResistFunctionOrSub("New", CObj(ctor))
        Console.WriteLine("コンストラクタを登録しました。")

        Dim mulFunc As Func(Of Foo, Integer, Foo) =
            Function(obj As Foo, value As Integer)
                    obj.Value *= value
                    Return obj
                End Function
        type.ResistFunctionOrSub("Mul", mulFunc)
        Console.WriteLine("Mulメソッドを登録しました。")
        Console.WriteLine("FooFoo型の準備が終わりました。")
        Console.WriteLine()

        Return result

    End Function

    Sub Main()

        'FooFoo型オブジェクトのインスタンスを生成する
        Dim info As ObjectInfo = GetFooFooObjectInfo()
        Dim ctor As Func(Of FooFoo) = info.GetFunctionOrSub("New")
        Dim obj As FooFoo = ctor()

        'メソッドを呼び出す
        Dim addValue As Integer = 10
        Dim f As Object = info.GetFunctionOrSub("Add")
        Dim addFunc = CType(f, Func(Of Foo, Integer, Foo))
        obj = addFunc(obj, addValue)
        Console.WriteLine("オブジェクトに{0}加算しました。", addValue)

        'プロパティのゲッターを呼び出す
        f = info.GetFunctionOrSub("Get_Value")
        Dim getter = CType(f, Func(Of Foo, Integer))
        Dim v As Integer = getter(obj)
        Console.WriteLine("オブジェクトの値は{0}です。", v)

        '新しいメソッドを呼び出す
        f = info.GetFunctionOrSub("Mul")
        Dim mul = CType(f, Func(Of Foo, Integer, Foo))
        Dim mulValue As Integer = 10
        obj = mul(obj, mulValue)
        Console.WriteLine("オブジェクトに{0}乗算しました。", mulValue)

        '再びプロパティのゲッターを呼び出す
        Dim v1 As Integer = getter(obj)
        Console.WriteLine("オブジェクトの値は{0}です。", v1)

        '間違った!
        Dim name As String = "ピヨ"
        Try
            f = info.GetFunctionOrSub(name)
        Catch ex As ArgumentException
            Console.WriteLine("FooFoo型に{0}関数は存在しません。", name)
        End Try

        '終了
        Console.WriteLine()
        Console.WriteLine("サンプル終了です。")
        Console.ReadLine()

    End Sub

End Module

このサンプルは、Fooオブジェクトを継承したFooFooオブジェクトを使用するというものです。継承をするとき子となるオブジェクトは、変更しない親オブジェクトの定義(プロパティ、関数、手続きなど)を改めて定義しません。それをどのようにして実現しているのかを表わしました。このサンプルを動かしコードをよく読めば、大まかなイメージが湧くと思います。
 見ての通り、継承の考え方そのものは単純です。一言でいうならば、同じことは何度も書かないです。継承を見れば、オブジェクト指向プログラミングは、人間のためにあるということが良くわかります。これほど単純な概念なのにも関わらず、継承は難しいといわれています。その理由は、原理ではなく使用法にあります。つづく...
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

インドリ

Author:インドリ
みなさん、はじめまして、
コンニチハ。

ボクは、無限の夢(infinity dream)を持つネタ好きな虹色の鳥インドリ(in dre)です。
色々な情報処理技術を啄ばむから楽しみにしてね。

http://twitter.com/indori
は別人による嫌がらせ行為です。
私とは関係ないので注意して下さい。
次はなりすましブログなどをするかもしれませんが、ここ以外でブログをするつもりがないので、ここ以外にインドリのブログがあったとしても無視してください。


何度言っても分からない人がいるので、ここにコメント欄へ書き込むときの注意事項を書きます。


一、社会人としてのマナーをわきまえましょう。
一、妄想に基づく書き込みを止めてください。
一、暴言の類は書かないで下さい。
一、某誹謗中傷サイトの書き込みは彼らの妄想に基づく書き込みですから無視して、ここへ書き込まないで下さい。
一、コメント書く前に他のコメントよく読んでから行って下さい。
一、言いがかかり等の行為を禁止します。
一、その他常識的に考えて迷惑なコメントはしないで下さい。


以上のルールを守れない人のコメントは削除します。



利用上の注意
ここに紹介してある文章およびプログラムコードは正確であるように心がけておりますが、内容を保証するものではありません。当サイトの内容によって生じた損害については、一切の責任を負いませんので御了承ください。


執筆したCodeZineの記事


【VB.NETで仮想CPUを作ろう】

  1. VB.NETで仮想CPUを作ろう
  2. レジスタの実装
  3. 仮想CPUのGUI化
  4. テストドライバの改良
  5. CPUの基礎動作の実装
  6. MOV命令の実装
  7. ADD命令実装
  8. SUB命令実装
  9. INC命令&DEC命令の実装と命令長
  10. MLU命令の実装とModR/Mについて
  11. DIV命令の実装とイベント設計について
  12. 機械語駆動式 関数電卓を作ろう!
  13. 機械語駆動式 関数電卓を作ろう! 解答編(前半)
  14. 機械語駆動式 関数電卓を作ろう! 解答編(後半)


【仮想ネットワーク実装でTCP/IPを学ぼう】
  1. TCP/IPの基礎と勘所
  2. ネットワークアクセス層の勘所
  3. インターネット層の勘所
  4. トランスポート層の勘所
  5. アプリケーション層の勘所
  6. セキュリティの基礎と仮想ネットワークの仕様
  7. GDI+と独自プロトコルの定義



【並列化】
インテル Parallel Studioを使って並列化プログラミングを試してみた
並列プログラミングの効率的なデバッグを実現する「Parallel Inspector」


【TBBシリーズ】
  1. インテル スレッディング・ビルディング・ブロックの概要
  2. インテルTBBから学ぶループの並列化
  3. スレッドセーフとインテルTBBのコンテナ
  4. インテルTBBのスレッドクラス


【OpenMPシリーズ】
  1. OpenMPの基礎構文
  2. OpenMPの実行時ライブラリと並列ループ
  3. OpenMPのメモリモデルとfork- joinモデル

最近の記事
最近のコメント
月別アーカイブ
カテゴリ
Ada (9)
COBOL (5)
C (9)
C++ (11)
C# (370)
D (25)
Java (8)
Perl (1)
Ruby (14)
PHP (2)
Boo (2)
Cobra (2)
LISP (6)
F# (33)
HTML (0)
XHTML (0)
CSS (0)
XML (0)
XSLT (0)
Scala (4)
WPF (0)
WF (2)
WCF (0)
LINQ (4)
MONO (5)
Linux (0)
MySQL (0)
ブログ内検索
リンク
最近のトラックバック
RSSフィード
ブロとも申請フォーム

この人とブロともになる

QRコード
FC2カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。