再定義とかオーバーライドという言葉の使い方で混乱してるかな。一度公式ドキュメントを読んで整理しよう。
なんかのサイトで出てきてる”再定義”ってのは、「継承先で、おなじなまえで、"てーぎ"すること」という一般的な言葉に過ぎない。
一方、「オーバーライド」ってのはJavaのドキュメントに仕様みたいなもんとして定義されてる言葉。
https://docs.oracle.com/javase/specs/jls/se20/html/jls-8.html#jls-8.4.8.1
”再定義”っていう言葉と「オーバーライド」は同じではない。
語弊があるかもしれないが、”再定義”は「オーバーライド」を含むと考えたらわかりやすいかも。
で、もう一つの公式っぽい単語「隠蔽」っていう言葉を知ってるかどうか。
https://docs.oracle.com/javase/specs/jls/se20/html/jls-8.html#jls-8.4.8.2
スタティックメソッドは「オーバーライド」(override)できない。
言語仕様として「オーバーライド」できるのはインスタンスメソッドだけだ。
なので、@Overrideアノテーションをスタティックメソッドに使うとコンパイルエラーになる。
しかし、staticメソッドも、継承先で同じ名前をつかって再定義することはできる。
つまり「クラスを継承して、継承先で、継承元に存在するスタティックメソッドと同じ名前、同じ引数のスタティックメソッドを定義」することはできる。
この場合、継承元のスタティックメソッドは「隠蔽」される(hiding)。
形式上おんなじ、”メソッドの再定義”を行っているとしても、「オーバーライド」している場合と「隠蔽」が起こっている場合では、下記のような違いが出る。
(なお、クラスメソッドでインスタンスメソッドを隠蔽しようとするとコンパイルエラーになる)
(わかりやすい例)
http://www.wisdomsoft.jp/123.html
まとめ
-
形式上、スタティックメソッドを"再定義"することは可能 =インスタンスメソッドのオーバーライドの形式と同じように「クラスを継承して、継承先で、継承元に存在するメソッドと同じ名前、同じ引数のメソッドを定義」することはできる。(これは「オーバーライド」ではない。元のメソッドは「隠蔽」される)
-
言語仕様として、スタティックメソッドを「オーバーライド」することはできなくされている。=スタティックメソッドに対して@overrideアノテーションを使うと、コンパイルエラーになる。
じゃあなんでそもそも、スタティックメソッドは「オーバーライド」できないの?
staticメソッドは、参照されるオブジェクトではなく参照の型に基づいて呼び出される=どのメソッドを呼び出すかが、コンパイル時に決定される。
「オーバーライド」は実行時の動的バインディングに依存するしくみになってるから、上記のようなstaticメソッドの仕様上、staticメソッドを「オーバーライド」することは原理的にできない。
(インスタンスメソッドはstaticメソッドと異なり、参照の型ではなく参照されてるオブジェクトの型に基づいて呼び出される=どのメソッドを呼び出すかが実行時に決定される)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/06/10 15:01 編集
退会済みユーザー
2023/06/11 02:05 編集
2023/06/10 16:49