/dev/null

(◞‸◟)

ポリモーフィズムとかの覚書

覚書程度に。

Java書いてるけど、オブジェクト指向よくわからない3大要素のトップ、ポリモーフィズム

そもそも綴り絶対覚えられないし、日本語にすると多態性とかいう聞いたことないものだしとりあえず死ね

継承→わかる

カプセル化→便利かは最初わからないけどわかる

多態性→なんだお前死ね

と思っています。

オーバーロード == 多態性みたいな認識(一部分でしかない)

まあ今でも全然わかってないけど、親クラスの変数に小クラスのインスタンスは入るけど逆は云々とかいうやつはそのまま覚えようとしても身につかないのでどういう原理で動くのかまとめてみた。

間違えてる可能性も高い


まずこういうクラスがある

class Parent {
    
    public void parent() {
        System.out.println("parent");
    }
}

class Child extends Parent {
    
    public void child() {
        System.out.println("child");
    }
}

ChildクラスはParentクラスを継承している普通のアレ

で、それをインスタンス化して使うときのコード

まず、親クラスな変数に小クラスのインスタンスを入れることを考える。

Parent parent = new Child();

このコードはコンパイルが通る

しかし、逆に小クラスの変数に親クラスのインスタンスを入れる場合は

Child child = new Parent();

これはコンパイルエラーになる。

Eclipseとか使ってればエラー吐くし、それでいいやでいいんだけど一応理由の一つくらい説明できるようになっておこうということで

Parentクラスの変数が実行できそうなメソッドは

public void parent()のみである

そして、childクラスはparentクラスを継承しているので必ずparentクラスを呼び出すことが出来る。

その逆にChildクラスの変数が実行できうるメソッドは、

public void parent()

public void child()

の2つである。

しかし、その変数の中にParentのインスタンスを入れることが出来たとしたら、中身はParentのインスタンスでしかないのでchild()メソッドは実行することができない。

子は親を知っているが、親は子が何を持っているか知らないのだ。

そして、Child変数がchild()を実行しようとしてNoMethodErrorを起こすのを未然に防ぐためにコンパイルエラーは通らない。

この原理が分かっていれば、どっちに入るんだっけ??っていうのが無くなるとは思う。気がする。

Threadクラスの実装を読んだらさらに理解が深まったというか、ThreadクラスにはRunnableインターフェースを持つクラスをインスタンスフィールドに持っている。

Runnableインタフェースをimplementsしているクラス == runメソッドを必ず持っているクラスということなので

Thread threadA = new Thread(Runnableをimplementsしたクラス)

というコードを書いても、Threadクラス内でRunnableクラスフィールドに格納することができるし、startメソッドとかでRunnableフィールドのrunメソッドを実行出来るよねって話。

結局Interfaceも多態性に影響するアレ。むしろInterFaceないのに多態性あっても仕方ねーってやつっぽい。

なんとなくまとめてみたけど、何言ってるかわからんな.....

要するに

オブジェクトが出来る行動は、中身のインスタンスじゃなくてその変数によって決まりそうな気がするね!?

ってことなのです。

もしかしたら、その中身のインスタンスに左右されるとかそういうことが真理かもしれないけどコンパイルエラー出るし(•́ω•̀)

まあJavaさんが型に厳しいので出来ることですね、はい。