- ベストアンサー
インスタンスの作成に関する質問
- JAVA初心者の質問ですが、インスタンスを作成する方法について調べています。
- 具体的には、JFrameクラスを継承したクラスのオブジェクトを生成する方法が分からず困っています。
- JFrameクラスとJFrame_Testクラスの違いや、JFrameクラスのオブジェクトを直接生成する方法が分からないので詳しく教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
オブジェクト指向言語を使う上で常識となっている概念にsubstitution principle (訳すと入れ替え原則) というものがあります。これは、サブクラスはスーパークラスと入れ替え可能という概念です。例えば、車というクラスを定義したときに、そのサブクラスとして消防車を定義しても、消防車は車の機能を全て持っているので車クラスと入れ替えて使うことができます。もちろん、消防車には消火という車にはないメソッドがあるはずですが、これがあっても車には違いありません。なお、車型の変数に消防車型を入れている場合は、実際の型 (actual type) は消防車であっても、見かけ上の型 (apparent type) は車になっているので、消火というメソッドは使えません。消火というメソッドを使う場合はキャストをしなくてはいけません。 ちなみに、なぜ継承があるかというと、プログラムを単純に書けるようになるからです。もし、継承がなければ例えば交通整理というメソッドを作るときに消防車の用の交通整理とスポーツカー用の交通整理と...とすべての車に対して交通整理というメソッドを作る必要がありますが、継承があれば車に対して交通整理メソッドを書けば車のサブクラスすべてにこの手のメソッドを書いたのと同じことになります。こうすることで、各種車に対してプログラムを書くという手間や車の種類が増えたときにさらにプログラムを書き足さないといけなくなるという手間を回避しています。 さて、このプログラムはJFrame_TestがJFrameを継承していて、JFrameのサブクラスとなっているのでJFrameの代わりとしてJFrame_Testを使ってプログラムを書く事ができます。この時、JFrameの代わりに使っているわけですから使えるメソッドはJFrameが持っているメソッドだけです。そして、同じ名前と引数のメソッドをJFrameとJFrame_Testで定義した場合は、JFrame_Testに定義されているメソッドの方がJFrameに定義されているメソッドよりも優先的に呼び出されます。もし、JFrame_Test型のメソッドを使いたい場合は一旦JFrame_Testにキャストして呼び出す必要があります。 > //JFrame_Test jf = new JFrame_Test(); > JFrame jf = new JFrame_Test(); > > と書き変えてやってもエラーもなく、正常に同じ動作をします。 > この両者は文法的にはどのように違うものなのでしょうか。 文法的に違う意味になります。JFrame_Test if = ...はJFrame_Test型の変数ifを定義したので、JFrame_Testと同じメソッドが使えますが、JFrame ifのはJFrame型の変数なのでJFrame型にあるメソッドしか呼び出すことができません。 > また、JFrame jf = new JFrame(); > とかいても、正常に動作します。 > これは、JFrame_Testではなく、JFrameという親クラスのオブジェクトを作っ > ているということでしょうか、以上宜しくお願いします。 そのとおりです。この場合、実際の型もJFrame_Testではないので、メソッドを実行した場合はJFrameのメソッドが呼ばれますし、JFrame_Testにキャストをすることもできません。
その他の回答 (1)
- toorisugari001
- ベストアンサー率80% (4/5)
前者様が完璧な回答をしていますので、補足ですが。 paintメソッドが例題としてどうかと思います。 定義しておき、 実体化すると内部で勝手に実行され続けるというものなので。 トラップメソッド(?)と勝手に呼んでいるのですが、 各Listenerクラスなどでよく見かけます。 public static void main(String args[]){ //JFrame jf = new JFrame_Test(); JFrame_Test jf = new JFrame_Test(); jf.setVisible(true); ///////////////////////////////////// jf.konbanwa(); ///////////////////////////////////// } public void konbanwa(){ this.setTitle("こんばんわ"); } jf.konbanwaを2通りのやり方で実行してみてください。 JFrame jf = new JFrame_Test(); の場合はシンボルが見つからず、コンパイルができないはずです。 変数jfが何を参照できるかという話ですよね? ちなみに JFrame jf = new JFrame_Test();としても ( (JFrame_Test)jf ).konbanwa(); とすれば実行できます。
お礼
hanabutakoさん、回答有難う御座います。 回答の内容から考えると、JFrame_Test()がJFrame()の メソッドをオーバーライドという考え方は理解できたのですが、 実際に JFrame jf = new JFrame_Test(); // JFrame_Test jf = new JFrame_Test(); としてプログラムを実行させると、フレームには、 "XYZ"という文字が表示されます。 これは、JFrame のメソッドが、JFrame_Test();にオーバーライド されたということでしょうか。 JFrame jf = new JFrame_Test();なら、JFrame のオブジェクト である、jf のメソッドが実行されているのなら、 フレームには文字は表示されないと思うのですが。 この考え方は間違っているのでしょうか。