質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

529閲覧

オブジェクト指向 操作にアクセスできるオブジェクトの制限は可能なのでしょうか?

cacapon

総合スコア21

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2020/01/26 13:54

前提・実現したいこと

オブジェクト指向の知識がぼんやりしてるので、改めて勉強中の者です。

数点の書籍とネットの記事を読んでおりましたが、探し方が下手なのか見つからず、こちらに質問した次第でございます。

質問内容ですが、
オブジェクトの操作(メソッド)を使う場合、
そのオブジェクトを使う側は指定する事が出来るのかと疑問に思い質問しました。
是なら、その方法を、
否なら、その理由を知りたく思います。

例えで言いますと…
お客・従業員・自販機オブジェクトの三つがあるとして…

自販機オブジェクトには
「商品を買う」と
「商品を補充する」機能があり

「商品を買う」機能を使うのは
お客・従業員どちらも利用できるが、
「商品を補充する」機能を使えるのは、従業員のみ、と言った場面を想定しています。

概念の勉強中なので、
回答としては図式化したものか、言葉として説明頂く事を希望しております。
勿論、説明として「〇〇の言語の場合でしたらこんな感じになります」とコードで回答頂いてもありがたいです。
(c,c++,c#,pythonでしたら多少の経験はございますので、それに近い形式の言語でしたら読む事は可能かと思われます)

今回の投稿は不慣れでありますので、
情報が足りない、質問のマナー等で失礼に当たる等もございましたらご連絡頂けばと思います。

それではよろしくお願いします、
ありがとうございました。

発生している問題・エラーメッセージ

あるメソッドの利用者を制限する表現方法が分からない。

該当のソースコード

ソースコードはございません。

試したこと

本質問に関連しそうな記事と書籍を数点読んだ程度であります。

メソッドの種類について調べ、
public protected privateがある事は存じておりますが、こちらは親子関係があるクラス同士で機能をどう制限するかの話で、違いそうですし…
結局有用な情報は得られませんでした。

補足情報(FW/ツールのバージョンなど)

特にございません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

自販機からみれば「自分に商品を補充するのが誰なのか?」なんて話はどうでもいい(あずかり知らぬこと),という考え方はダメなんでしょうか.

「従業員にしか補充してほしくない自販機(インスタンス)」があるのであれば,そのインスタンスに補充する手段(インタフェースだったりあるいはインスタンスの存在だったり)を「客」にさらさなければよい.

自販機側で「こいつは従業員だな」とか区別してどうこうするのではなくて.

投稿2020/01/27 01:42

fana

総合スコア11654

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cacapon

2020/05/28 09:51

だいぶ期間が空いてしまい申し訳ございません… 回答ありがとうございます! なるほど!「そいつを知らなきゃ、それは使われない」という考え方なのですね。 こちらについては回答は不要というか…私がほっぽりぱなしで全く動いてなかったので 申し訳ない気持ちがいっぱいなので、独白のような感じです… ちょっと私の知識力だと、分からないのですが… インターフェースって誰にでも見えているところに公開しているものなのかな? って思ってしまったので、そういう見つけなくする方法があるのでしょうか? インスタンスも特定の所で作られたものを、客や従業員が見に来るわけで… その見に来た人によってインスタンスなり、インターフェースを隠したり隠さなかったり出来るのなら fanaさんがおっしゃっているやり方は出来るのかなぁと思うんですけど… 今の私にはどうしたらそれが出来るかが分かりませんでした…
guest

0

こんにちは。

既に解決していますが、面白いテーマなのでちょっと意見を述べさせて下さい。

これは、ある種のアクセス制限(隠蔽)機能と思います。
多くのオブジェクト指向言語は、public, protected, privateの3種類のアクセス制限機能を持ちます。
更にC++はfriend指定というアクセス制限を回避する機能を持ちます。

「従業員クラス」を「自動販売機クラス」のfriendとして定義し、「商品を補充する」メソッドをprivate定義するという使い方が考えられます。
ただし、「従業員クラス」は「自販機クラス」の全てのprivateメンバーにアクセスできるようになるという問題があります。これはこれでprivateを台無しにするので悩ましいです。(親しい仲でもプライバシーは確保したいものです。)

kgreenjpさんが提案されているような、引数の型で制限するのは多くのオブジェクト指向言語で対応可能ですし、friendのような全てにアクセスできてしまう問題はありません。しかし、本質的に渡す必要がない引数を渡している場合は、改悪(パラメータを削除)するプログラマーがでてくるリスクはあると思います。コメントをきっちり書いておくことで回避できると思います。


ところで、その辺りのアクセス制限機能を豊富にして、特定のクラスに特定のメンバ変数へのアクセスのみを許すような言語仕様を策定することも可能と思いますし、そのような機能を検討された言語開発者は多数いるだろうと思います。しかし、C++のfriendさえ多くのオブジェクト指向言語はネグってます。アクセス制限機能を複雑にすると、学習難易度が上がりすぎるのではないかと思います。

そして、「自販機クラス」のメンバーにアクセスするプログラムを書くのはプログラマーです。プログラマーが「間違って」アクセスしてはいけないメンバーをアクセスできないようにするのが、これらのアクセス制限機能です。
「悪意のあるプログラマー」が「悪意のあるプログラム」を忍び込ませることを制限できるような高度な機能ではありません。フールプルーフ的な機能ですので、ある程度の「割り切り」も必要かと思います。

投稿2020/01/27 03:17

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cacapon

2020/05/28 09:42

だいぶ時間が空いてしまって申し訳ございませんが、深い知識に基づかれた意見に対するコメント。 まことにありがとうございます! 必要最低限の情報を、特定の人が渡すのがベスト… それが理想なのでしょうか、それを実現できる言語が(有名どころでは?)ない… 興味深いお話でした!
guest

0

ベストアンサー

単純な方法としては、型を確認する方法です。

自販機に商品を補充する機能を呼び出したものを確認させます。
例えば
引数に送り主を取り(sender) senderは何かを確認させる(isなど)
またはそれぞれの型にキャスト(asなど)し、キャストできるかを確認させるなどですね。

単純な方法ですので、安全ではないです。しかし、単純に制限はかかります。
インターフェースを用いる実装のほうがスマートです。
ほかの方の回答もありますので、ご参照ください。

投稿2020/01/26 13:57

編集2020/01/26 15:21
kgreenjp

総合スコア97

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cacapon

2020/01/26 14:08

早速の回答ありがとうございます! 型を確認する…ですか? と伺おうと思っておりましたら、具体的な例も記載頂きましてありがとうございます!理解出来ました!
hayataka2049

2020/01/26 14:12

その場合、従業員オブジェクトを誘拐してくれば、従業員でなくても補充できてしまいます。安全とは言えないかもしれません。
Zuishin

2020/01/26 14:32

こんなことを聞きたかったんでしょうか。これだと例えば犯罪者オブジェクトが適当な従業員オブジェクトを引数に自販機オブジェクトのメソッドを呼び出せてしまいます。 従業員オブジェクトしか呼び出せないメソッドを作るには、C# であれば自販機クラスを従業員クラスの内部クラスにし、private メソッドを作ることで実現できます。あるいは同じモジュールにして internal メソッドを実装するのもよくあるパターンです。
kgreenjp

2020/01/26 15:24 編集

従業員クラスの内部クラスに実装する方法ですが、自動販売機ではないように思えますがいかがでしょうか? その他の実装方法も考慮していただけるよう。回答に追記させていただきました。
Zuishin

2020/01/27 00:16

私へのコメントですか? 自動販売機は実際実装したい仕様の一例でしかないと認識しています。自販機を実装することなどないでしょうから、自販機について煮詰める必要はないのでは? 二つの設計例を上げていますから、状況に合わせて選ぶことができます。
Zuishin

2020/01/27 00:28 編集

あるいはよくあるのがクラスに属する読み取り専用プロパティです。このプロパティは外のクラスからは読み取りしかできませんが、親クラスからは書き込みできます。 これを内部では List<T> として実装し、ReadOnlyList<T> として公開するなどが考えられます。 質問者さんの真に求めるものがもしこれであった場合、自販機の概念は意味をなしません。
cacapon

2020/05/28 10:04

Zuihsinさん、hayatakaさん、kgreenjpさん、その後もコメントや回答を頂きありがとうございます! そして、たくさん回答いただいたのにお返事が遅くなってしまったこと、お詫びいたします。 皆さんの回答のおかげで、私が質問した内容は そう簡単に解決する問題ではないのかなぁという気がしてきました(笑 内部に含める…は想像していたのと形が違うのかなと。 自販機の中に従業員が入っているというのはイメージ違いますし… 型確認も、外部が悪意あるインスタンスだと形無しなのですね… internalは…ごめんなさい分かりませんので自分で調べてみます。 最後の読み取り専用プロパティも今回の例題で実現したい事とはズレてしまう気がしますし… 色々考えさせる回答を多くいただき感謝いたします。 皆さんからいただいたいろいろな解決法をもう一度見て、 どの形が私が実現したかったことに適しているか考えてみることにします。
guest

0

大抵の場合はインターフェースを用いてユーザーに公開する範囲を狭められます。
C#でしたらinternal指定ができます。

投稿2020/01/26 14:44

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cacapon

2020/05/28 09:52

asm さん、回答ありがとうございます! 解答からだいぶ時間が経ってのお礼で申し訳ございません… internal…ちょっと勉強不足なので調べてみます! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問