tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル多重継承について
記事No5313
投稿日: 2007/04/11(Wed) 10:14
投稿者ひでと
お世話になります。
製品の重量を求めるプログラムを作ろうとして、根本的な問題でつまづいています。
お知恵をお貸しください。
製品は、分類方法が3タイプあります。
断面形状 分類方法1
 外一度曲げ
 外二度曲げ
 内曲げ
水平トレイ 分類方法2
 ラダートレイ
 鋼板トレイ
種類 分類方法3
 ストレート
 水平曲がり
 ... (20種類ほどあります。)

したがって 1つの製品は 例えば「外一度曲げ」でかつ「ラダートレイ」でかつ「ストレート」
であるということができます。それぞれの製品に属性があり、重量の計算方法が異なっています。

これをクラスを用いて表現するには、「多重継承」(?)が必要のように思いました。
無理やりに 「Inherits」と「Namespace」を使ってみたのですが、
「Interface」を使う方法があるようにヘルプでみました。どちらが良いのでしょうか?
または、また私の全くの間違いなのか教えていただければと思います。

続けてクラスのソースを部分的に入れますので、ご指摘ください。

[ツリー表示へ]
タイトル多重継承について2
記事No5314
投稿日: 2007/04/11(Wed) 10:16
投稿者ひでと
Public Class ラダートレイ
    Private サイド材板厚value As Double
    Private クロス材板厚value As Double
    Private new底曲げ As Double
    Public Property サイド材板厚() As Double
        Get
            Return サイド材板厚value
        End Get
        Set(ByVal value As Double)
            サイド材板厚value = value
        End Set
    End Property
    Public Property クロス材板厚() As Double
        Get
            Return クロス材板厚value
        End Get
        Set(ByVal value As Double)
            クロス材板厚value = value
        End Set
    End Property
    Public Property 底曲げ() As Double
        Get
            Return new底曲げ
        End Get
        Set(ByVal value As Double)
            new底曲げ = value
        End Set
    End Property

End Class


Namespace ラダートレイ
    Public Class 外一度曲げ
        Inherits 水平トレイ.ラダートレイ
        Private new縁曲げx As Double
        Public Property 縁曲げx() As Double
            Get
                Return new縁曲げx
            End Get
            Set(ByVal value As Double)
                new縁曲げx = value
            End Set
        End Property
    End Class
End Namespace
Namespace 鋼板トレイ
    Public Class 外一度曲げ
        Inherits 水平トレイ.鋼板トレイ
        Private new縁曲げx As Double
        Public Property 縁曲げx() As Double
            Get
                Return new縁曲げx
            End Get
            Set(ByVal value As Double)
                new縁曲げx = value
            End Set
        End Property
    End Class
End Namespace


Namespace ラダートレイ
    Namespace 外一度曲げ
        Public Class ストレート
            Inherits 断面形状.ラダートレイ.外一度曲げ
            Private newW As Double
            Public Property W() As Double
                Get
                    Return newW
                End Get
                Set(ByVal value As Double)
                    newW = value
                End Set
            End Property
        End Class
    End Namespace
End Namespace
(以下は省略)

[ツリー表示へ]
タイトルRe: 多重継承について
記事No5315
投稿日: 2007/04/11(Wed) 10:52
投稿者魔界の仮面弁士
> それぞれの製品に属性があり、
「属性」ではなく、「プロパティ」では?

> これをクラスを用いて表現するには、「多重継承」(?)が必要のように思いました。
継承だと破綻しそうなので、委譲で実装した方が楽かも。
あるいはメンバをコレクション化してしまうとか。(DataTableのように)

[ツリー表示へ]
タイトルRe^2: 多重継承について
記事No5324
投稿日: 2007/04/12(Thu) 13:01
投稿者ひでと
ありがとうございます。
> > それぞれの製品に属性があり、
> 「属性」ではなく、「プロパティ」では?
申し訳ありません。そうだと思います?
>
> > これをクラスを用いて表現するには、「多重継承」(?)が必要のように思いました。
> 継承だと破綻しそうなので、委譲で実装した方が楽かも。
残念ながら「委譲で実装」の意味が良くわかりません。
クラスの利用は理解できない部分が多くて、何度も挫折中です。

> あるいはメンバをコレクション化してしまうとか。(DataTableのように)
ちょっと違う方法だと思いますが(?)、
現在、分類、断面、種類を参照する「トレイ」というクラス
から考えてみています。もう少し検討してみます。

Public Class トレイ
    Private new分類 As New Object
    Private new断面 As New Object
    Private new種類 As New Object
    Public Property 分類() As Object
        Get
            Return new分類
        End Get
        Set(ByVal value As Object)
            new分類 = value
        End Set
    End Property
    Public Property 断面() As Object
        Get
            Return new断面
        End Get
        Set(ByVal value As Object)
            new断面 = value
        End Set
    End Property
    Public Property 種類() As Object
        Get
            Return new種類
        End Get
        Set(ByVal value As Object)
            new種類 = value
        End Set
    End Property
End Class

[ツリー表示へ]
タイトルRe^3: 多重継承について(1)
記事No5329
投稿日: 2007/04/12(Thu) 15:14
投稿者ひでと
自己レスになります。
ソリューションエクスプローラでフォルダを使用表示することが出来るのに気がつきました。
また フォルダの中に作成したクラスにNamespaceを利用するとフォルダがどこにあっても
Namespaceに記載された名前空間にコンパイルできることがわかり、
ソリューションエクスプローラで階層的に表示することができました。

実際のクラスですが、
分類、断面、種類を Object型で参照する「トレイ」クラスを作り、
「分類」フォルダーに「鋼板トレイ」、「ラダートレイ」
「断面」フォルダーに「外一度曲げ」...
「種類」フォルダーに「ストレート」、「水平曲がり」...
の各クラスを作成しました。
それぞれは Namespace を用いて、例えば

Namespace 分類
    Public Class 鋼板トレイ
        Private new本体板厚 As Double
        Public Property 本体板厚() As Double
            Get
                Return new本体板厚
            End Get
            Set(ByVal value As Double)
                new本体板厚 = value
            End Set
        End Property
    End Class
End Namespace
のようにしました。

「トレイ」クラスは
Public Class トレイ
    Private new分類 As New Object
    Private new断面 As New Object
    Private new種類 As New Object
    Public Property 分類() As Object
        Get
            Return new分類
        End Get
        Set(ByVal value As Object)
            new分類 = value
        End Set
    End Property
    Public Property 断面() As Object
        Get
            Return new断面
        End Get
        Set(ByVal value As Object)
            new断面 = value
        End Set
    End Property
    Public Property 種類() As Object
        Get
            Return new種類
        End Get
        Set(ByVal value As Object)
            new種類 = value
        End Set
    End Property
End Class
となっています。

[ツリー表示へ]
タイトルRe^3: 多重継承について(2)
記事No5330
投稿日: 2007/04/12(Thu) 15:25
投稿者ひでと
ひきつづいて
フォルダーを階層的に構成しました。
「鋼板トレイ」フォルダーの中に「外一度曲がり」フォルダーを作り、さらにその中に
「ストレート」フォルダーを作成しました。
その「ストレート」フォルダーの中に「ストレート」クラスを作成しました。
「ストレート」クラスは「トレイ」クラスを継承し、「New」のプロシージャで
「鋼板トレイ」、「外一度曲げ」、「ストレート」のオブジェクトを取得しました。
その際、Namespaceを用いて 「鋼板トレイ.外一度曲げ.ストレート」という形で
参照できるようにしました。

Namespace 鋼板トレイ.外一度曲げ
    Public Class ストレート
        Inherits トレイ
        Public Sub New()
            Me.分類 = New 分類.鋼板トレイ
            Me.断面 = New 断面.外一度曲げ
            Me.種類 = New 種類.ストレート
        End Sub
    End Class
End Namespace
以上。検討してみた方法です。
とりあえず、この方法で試してみようと思います。
ご指導ありがとうございました。また、よろしくお願いします。

[ツリー表示へ]
タイトルRe^4: 多重継承について(2)
記事No5333
投稿日: 2007/04/12(Thu) 16:19
投稿者魔界の仮面弁士
> ひきつづいて
> フォルダーを階層的に構成しました。

# もはや、元の件名(多重継承)とは、何の関係も無くなっているような…。(^^;
# そもそも、[継承]と[名前空間]と[ソリューションのフォルダ構造]は無関係かと。

[ツリー表示へ]
タイトルRe^5: 多重継承について(2)
記事No5334
投稿日: 2007/04/12(Thu) 16:29
投稿者ひでと
> > ひきつづいて
> > フォルダーを階層的に構成しました。
>
> # もはや、元の件名(多重継承)とは、何の関係も無くなっているような…。(^^;
> # そもそも、[継承]と[名前空間]と[ソリューションのフォルダ構造]は無関係かと。

始の質問ですが、骨子としては
「3種類の分類方法があるものを、クラスに構造的に作成したい。」
という趣旨でありました。

私が、薄学なために「多重継承」やら「名前空間」などにとらわれてしまい、
あのような投稿になってしまいました。ご迷惑をおかけしました。
これからも、タイトルと異なった内容になってしまうことがあるかと思いますが、
それは、本意ではないのです。改めてお詫びします。また、よろしくお願いします。

[ツリー表示へ]
タイトルRe^6: 多重継承について(2)
記事No5339
投稿日: 2007/04/13(Fri) 11:37
投稿者るしぇ
> 始の質問ですが、骨子としては
> 「3種類の分類方法があるものを、クラスに構造的に作成したい。」
> という趣旨でありました。
分類するだけなら、クラスにする必要も無くって、Enum でも使えば
いいと思うんですよ。
まあ、それぞれの分類ごとに何か値を返すみたいだから、そこを
クラスにする方が良いのかもしれないけど、結局、その戻り値の
基となる値は誰の状態なのでしょうか?製品のプロパティなら、全ての
プロパティを製品が持ってて、Enum の違いで返す値を変更するだけでも
いいのでは?。

それぞれの分類方法で何が共通なのか?共通処理をまとめられるのか?
その後のメンテナンス作業でどんな改造が発生するのか?
実際に目的に応じた設計にするには、それぞれの分類についても理解
しておく必要があります。ところが。。。トレイとか専門用語使われても、
どうしたいのかが全く伝わりませんでした。

目的に応じて設計は全く変わるから、この状態でアドバイスは難しいです。
むしろ『継承』『名前空間』などの有効性が分かるような、小学生でも
理解できるような簡単な内容で質問した方が良かったのでは?

複数の概念を比べて選択するには、それぞれの基本的な知識を持っている
ことが前提で、そうでないと回答を得ても理解できないでしょう?
まずは『継承』って何?どんな時に使うの?から始めるべきレベルなの
では?と感じるのですが。。。

    Sub Test()
        Dim seihin As 製品

        seihin = New 製品(製品.分類方法1.内曲げ, 製品.分類方法2.鋼板トレイ, 製品.分類方法3.ストレート)
        seihin.Set基本重量(100)
        MessageBox.Show(seihin.重量計算.ToString)

        MessageBox.Show(製品A.断面形状.ToString & 製品A.水平トレイ.ToString & 製品A.種類.ToString & 製品A.基本重量.ToString)
        seihin = New 製品A
        MessageBox.Show(seihin.重量計算.ToString)

        MessageBox.Show(製品B.断面形状.ToString & 製品B.水平トレイ.ToString & 製品B.種類.ToString & 製品B.基本重量.ToString)
        seihin = New 製品B
        MessageBox.Show(seihin.重量計算.ToString)
    End Sub

    Public Class 製品
        Protected _基本重量 As Double
        Protected _断面形状 As 分類方法1
        Protected _水平トレイ As 分類方法2
        Protected _種類 As 分類方法3

        Protected Sub New()
            Call Clear()
        End Sub

        Public Sub New(ByVal 断面形状 As 分類方法1, ByVal 水平トレイ As 分類方法2, ByVal 種類 As 分類方法3)
            Me.New()
            _断面形状 = 断面形状
            _水平トレイ = 水平トレイ
            _種類 = 種類
        End Sub

        Public Overridable Sub Clear()
            _基本重量 = 0
            _断面形状 = 分類方法1.外一度曲げ
            _水平トレイ = 分類方法2.ラダートレイ
            _種類 = 分類方法3.ストレート
        End Sub

        Public Overridable Sub Set基本重量(ByVal 重量 As Double)
            _基本重量 = 重量
        End Sub

        Public Enum 分類方法1
            外一度曲げ
            外二度曲げ
            内曲げ
        End Enum

        Public Enum 分類方法2
            ラダートレイ
            鋼板トレイ
        End Enum

        Public Enum 分類方法3
            ストレート
            水平曲がり
        End Enum

        Public Function 重量計算() As Double
            Dim 重量Temp As Double
            重量Temp = _基本重量

            Select Case _断面形状
                Case 分類方法1.内曲げ
                    重量Temp = 重量Temp * 1.5
                Case 分類方法1.外一度曲げ
                    重量Temp = 重量Temp * 2 + 1.01
                Case 分類方法1.外二度曲げ
            End Select

            Select Case _水平トレイ
                Case 分類方法2.ラダートレイ
                    重量Temp = 重量Temp + 300
                Case 分類方法2.鋼板トレイ
                    重量Temp = 重量Temp + 200
            End Select

            Select Case _種類
                Case 分類方法3.ストレート
                Case 分類方法3.水平曲がり
            End Select

            Return 重量Temp
        End Function
    End Class

    Public Class 製品A
        Inherits 製品

        Public Shared ReadOnly 基本重量 As Double = 500
        Public Shared ReadOnly 断面形状 As 製品.分類方法1 = 製品.分類方法1.外一度曲げ
        Public Shared ReadOnly 水平トレイ As 製品.分類方法2 = 製品.分類方法2.ラダートレイ
        Public Shared ReadOnly 種類 As 製品.分類方法3 = 製品.分類方法3.ストレート

        Public Sub New()
            MyBase.New(断面形状, 水平トレイ, 種類)
            MyBase._基本重量 = 基本重量
        End Sub

    End Class

    Public Class 製品B
        Inherits 製品

        Public Shared ReadOnly 基本重量 As Double = 200
        Public Shared ReadOnly 断面形状 As 製品.分類方法1 = 製品.分類方法1.内曲げ
        Public Shared ReadOnly 水平トレイ As 製品.分類方法2 = 製品.分類方法2.鋼板トレイ
        Public Shared ReadOnly 種類 As 製品.分類方法3 = 製品.分類方法3.水平曲がり

        Public Sub New()
            MyBase.New(断面形状, 水平トレイ, 種類)
            MyBase._基本重量 = 基本重量
        End Sub

        Public Overrides Sub Clear()
            _基本重量 = 基本重量
            _断面形状 = 断面形状
            _水平トレイ = 水平トレイ
            _種類 = 種類
        End Sub
    End Class

[ツリー表示へ]
タイトルRe^7: 多重継承について(2)
記事No5342
投稿日: 2007/04/13(Fri) 12:33
投稿者ひでと
ご指導ありがとうございます。
> > 始の質問ですが、骨子としては
> > 「3種類の分類方法があるものを、クラスに構造的に作成したい。」
> > という趣旨でありました。
> 分類するだけなら、クラスにする必要も無くって、Enum でも使えば
> いいと思うんですよ。
> まあ、それぞれの分類ごとに何か値を返すみたいだから、そこを
> クラスにする方が良いのかもしれないけど、結局、その戻り値の
> 基となる値は誰の状態なのでしょうか?製品のプロパティなら、全ての
> プロパティを製品が持ってて、Enum の違いで返す値を変更するだけでも
> いいのでは?。

既製品の重量を求める場合のことを言っておられるのでしょうか?
それならば (私の得意の)Select Case でなんとかなるかと思いますが...。
実際は、最終の製品は注文生産で、一品一品違うのです。
したがって、重量も一品一品異なってきます。ただ、分類すると3通りの分類方法が考えられる
という状態です。

「したがって 1つの製品は 例えば「外一度曲げ」でかつ「ラダートレイ」でかつ「ストレート」
であるということができます。それぞれの製品に属性があり、重量の計算方法が異なっています。」
という表現は、あいまいでした。

>
> それぞれの分類方法で何が共通なのか?共通処理をまとめられるのか?
> その後のメンテナンス作業でどんな改造が発生するのか?
> 実際に目的に応じた設計にするには、それぞれの分類についても理解
> しておく必要があります。ところが。。。トレイとか専門用語使われても、
> どうしたいのかが全く伝わりませんでした。
>
> 目的に応じて設計は全く変わるから、この状態でアドバイスは難しいです。
> むしろ『継承』『名前空間』などの有効性が分かるような、小学生でも
> 理解できるような簡単な内容で質問した方が良かったのでは?
>
> 複数の概念を比べて選択するには、それぞれの基本的な知識を持っている
> ことが前提で、そうでないと回答を得ても理解できないでしょう?

質問するのはとても難しいです。
「会社で作っている物の重量を計算したいけど、どうすればよいですか?
教えてください。」といって「例えば、こういう製品があります。...」
と続けても、「ふざけるな!!!」といわれるのが当たり前です。
ご指導いただく為には、なにか元になるもの(例えば今回の場合のように)を見てもらおうと
思いました。

> まずは『継承』って何?どんな時に使うの?から始めるべきレベルなの
> では?と感じるのですが。。。

継承は、「元となるクラスの全てのプロパティをそのまま使用可能にするもの」
と理解していますが、
「どんな時につかうの?」
これに関しては、今一理解できません。
「こんな事がしたいけど、どうしたらいいのだろう?」から考えています。
何冊もオブジェクト指向に関する本を買って読んでも、中々「どうしたらよいのだろう?」
の答えは得られませんでした。
今回も、間違った方向に走ってしまいました。レベルの低さは努力しますのでよろしくお願いします。

[ツリー表示へ]
タイトルRe^8: 多重継承について(2)
記事No5343
投稿日: 2007/04/13(Fri) 15:32
投稿者るしぇ
>実際は、最終の製品は注文生産で、一品一品違うのです。
>したがって、重量も一品一品異なってきます。ただ、分類すると3通りの分類方法が考えられる
>という状態です。
だーかーらー。そーゆー仕様で考えられる数パターンのうちの1個を
サンプルコードとして書いたと思うんですが???
サンプルコードを解析した?製品Aでも基本重量の初期値は決まってるけど、
Set基本重量で変更可能だよ?

>「会社で作っている物の重量を計算したいけど、どうすればよいですか?
>教えてください。」といって「例えば、こういう製品があります。...」
最初の質問ってその日本語をそのままコードにしただけだよね?
「ふざけるな!!!」って言われるとされてる質問と大差ないとも思いますが(^^;)
>実際は、最終の製品は注文生産で、一品一品違うのです。
こう聞くとボクは某PCメーカーの注文生産を思い浮かべるわけです。
PCのモデルAにはDVDRWの1と2があって…とかいう例なら
『あー。部品が違うと重量変わるよね』
『発送の時に総重量を計算する必要があるよね』
って直感的に分かるわけです。この掲示板を利用している80%の人が分かり、
小学生でも分かる可能性のある質問になるはずです。

これがラダートレイだの鋼板トレイだの言われても
『ladderならはしごだから穴が空いてるのかな?鋼板?板だから穴が無い分重いのかな?』
って疑問ばかりで、何も有効な情報が伝わってきません。ましてや曲げなんて
言われても、そっちのほうが「ふざけるな!!!」では?(^^;)

ところで、某PCメーカーの注文生産だとしても、魔界の仮面弁士さんが
> あるいはメンバをコレクション化してしまうとか。(DataTableのように)
って書いてるけど、データベースに部品テーブル作ってしまえば終わっちゃうわけです。
極端な話、VB側では
    Public Class 製品
        Public 部品テーブル As DataTable
    End Class
だけで終わります。総重量は、部品テーブルのレコード数だけ、部品ごとの
重量を足せばいいんです。そんな関数1個を実装すれば終了です。
分類が何種類あろうと、必要な処理が部品の総重量を求めるだけなら
分類する必要がありません。一切合財省略してもよい情報です。

「そんなものを質問してるはずは無い!!!」…と思いたいわけですw。
だから、わざわざ、重量計算()で、分類に応じて、ただの合計でない
計算まで作ってあるのに。。。

> 既製品の重量を求める場合のことを言っておられるのでしょうか?
> それならば (私の得意の)Select Case でなんとかなるかと思いますが...。
いままでの情報では Select Case でできるものをうだうだ難しく作ろうと
しているだけにしか思えませんでした。

実現できない(したい)部分の、核となる仕様の情報をください。

    Sub Test2()
        Dim seihin As New 製品
        Dim mokuzai As 木材
        Dim goukei As Double

        mokuzai = New クロス材
        mokuzai.SetSize(5.7, 20.8, 500.3)
        seihin.部品コレクション.Add(mokuzai)

        mokuzai = New サイド材
        mokuzai.SetSize(5.7, 60.7, 500.3)
        seihin.部品コレクション.Add(mokuzai)

        goukei = 0
        For Each mokuzai In seihin.部品コレクション
            goukei += mokuzai.重量計算
        Next

    End Sub

    Public Class 製品
        Public 部品コレクション As New Collection
    End Class

    Public Class 木材
        Protected _板厚value As Double
        Protected _板幅value As Double
        Protected _板長value As Double
        Protected _密度value As Double

        Public Sub New(ByVal 密度 As Double)
            _密度value = 密度
        End Sub

        Public Sub SetSize(ByVal 厚さ As Double, ByVal はば As Double, ByVal 長さ As Double)
            _板厚value = 厚さ
            _板幅value = はば
            _板長value = 長さ
        End Sub

        Public Function 重量計算() As Double
            Return _板厚value * _板幅value * _板長value * _密度value
        End Function
    End Class

    Public Class クロス材
        Inherits 木材
        Public Shared ReadOnly 密度 As Double = 1.5

        Public Sub New()
            MyBase.New(密度)
        End Sub
    End Class

    Public Class サイド材
        Inherits 木材
        Public Shared ReadOnly 密度 As Double = 2.3

        Public Sub New()
            MyBase.New(密度)
        End Sub
    End Class

[ツリー表示へ]
タイトルRe^9: 多重継承について(2)
記事No5344
投稿日: 2007/04/13(Fri) 22:22
投稿者ひでと
ありがとうございます。(自宅から送信しています。)
製品は、鉄板を切って曲げて溶接して作ります。
重量は鉄板の比重と鉄板の面積から計算します。
製品はそのタイプで分類すると、2×3×20=120 通りのタイプに分かれます。
実際は、さらに別の系統のものがありますので 300種類位になります。

300種類はその形だけでの分類ですので、板の厚さ、幅、高さ、長さ、角度など
、色々な寸法によって一品一品はすべて違うことになります。
また、その重量を計算するためには、一つの品物につき数十行で表わされる計算式が必要となります(主として三角関数を多用)。
それらの製品には当然付属品がつきますが、その寸法も製品の寸法に影響されます。
また、付属品の扱いですが、ある時は製品の重量に含む場合もあり、別に計上する場合もあります。
文章にすると複雑でまだまだ全く表現しきれないのですか、検索サイトで「ケーブルトレイ」
と検索すると、家の会社が出てくるようです。

また、重量計算をしたいと言いましたが、そのほかにCADとつなげて図面を自動的に作成したり、
製作工程の「板取り」という作業を自動化したりと、希望はまだまだあります。
実はデータベースを利用して重量計算は自動化しておりますが、不満な点が多く根本から作り直したいのです。
また、「板取り」のプログラムはVB6で作り実用しておりますが、それらは関連が取れないため満足できない状況です。

300種類の計算をする為に300個のクラスを作り、それを整理する必要があったのです。
Re^3 で考えた方法で一応作業しております。今のところ破たんしていませんのでもう少し
作業を進めてみたいのです。

[ツリー表示へ]