クラス変数がクラスに属していないからだ。クラスではなく、クラス階層に属しているのだ。
・・・略・・・
多くの Rubyist はクラス変数を使わずにクラスインスタンス変数を使っている。
main のコンテキストで定義されたクラス変数は置いとくとして、Java 上がりとしては、なんだそれって感じ・・・。
クラス変数を使った場合
class A @@name = 'original name' def self.name @@name end def self.name=(name) @@name = name end end class B < A end puts A.name #=> class_instance_variable puts B.name #=> class_instance_variable A.name = 'new name' B.name = 'B name' puts A.name #=> B name puts B.name #=> B name
クラス変数の変更はサブクラスにも影響する。
クラスインスタンス変数を使った場合
class A @name = 'original name' def self.name @name end def self.name=(name) @name = name end end class B < A end puts A.name #=> original name puts B.name #=> nil A.name = 'new name' B.name = 'another name' puts A.name #=> original name puts B.name #=> another name
クラスインスタンス変数の場合は継承関係に影響しない。
で、java ってどうだったっけと不安になったので確認。
public class Succession { public static String name = "original name"; } public class SubSuccession extends Succession { } public class Main { public static void main(String args[]) { System.out.println(Succession.name); //=> original name System.out.println(SubSuccession.name); //=> original name Succession.name = "new name"; SubSuccession.name = "another name"; System.out.println(Succession.name); //=> "another name" System.out.println(SubSuccession.name); //=> "another name" } }
Java もサブクラスに影響する。Java の挙動って "こんな動きだったっけ?" と違和感を感じるのはなんだろう。static な変数をサブクラスが意識して使うってシチュエーションが無い(ほとんど使ったことが無い)からだろうか。
Java でクラスインスタンス変数は・・・ないなぁ。static な変数のスコープを private にしてサブクラスからは触らせないようにする程度か。
Ruby のクラスインスタンス変数も使いどころがよく分からないのはメタプログラミングしてないからか。