LoginSignup
3
4

More than 5 years have passed since last update.

Protectedなメンバ変数を書き換えるどうでもよい方法

Last updated at Posted at 2015-07-04

問題

Base、及びそれを継承しているDerivedがあります。

Base.java
public class Base {
    protected String message = "Base";

    public String inspect() {
        return "I'm " + message;
    }
}
Derived.java
public class Derived extends Base {
    public Derived() {
        super.message = "Derived";
    }
}

Derived#inspect()を呼び出した時、I'm crackedと表示させるにはどうすれば良いか?
- リフレクションは使わない
- Base, Derivedはもちろん変更しない
- 異なるパッケージにファイルを追加して対応する

Test.java
public class TestA {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.message = "cracked";
        // ^これはmessageが見えないのでエラーになる
        System.out.println(derived.inspect());
    }
}

解答

こんな感じで、Baseを継承したCrackerクラスを用意。
その中のメソッドで置き換えます。

Cracker.java
public class Cracker extends Base {
    public void crackDerived(Derived derived) {
        derived.message = "hacked";
    }
}
Test.java
public class TestA {
    public static void main(String[] args) {
        Derived derived = new Derived();
        Cracker cracker = new Cracker();
        cracker.crackDerived(derived);
        System.out.println(derived.inspect());
    }
}

結論

  • Javaのアクセス修飾子はインスタンス単位ではなくクラス単位。
  • 継承関係が兄弟関係にあるクラスでもprotectedフィールドが見える。
  • なんで?
3
4
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4