JavaでIoの構造っぽいものを(超簡単に)書いてみる
超簡単に、ですよ。循環継承はループから抜け出せませんので。
オブジェクトには、slotマップとprotosリストがあって、slotでそのオブジェクトが独自に持つデータを管理し、protosでそのオブジェクトの親オブジェクトを管理する。slotが呼ばれた場合、自分のslotにあればそれを返却し、なければ親オブジェクトを参照し、あればそれを返却する。だから、親オブジェクトのslotにあるキーと同名のキーでslotを追加すると、自分とこのslotで管理している値を返す。
委譲で継承を実現してるような感じ。
slotは値だけじゃなくメッセージ、つまりメソッドも管理できる。んだけど、その辺はまぁ取り合えず的に。
import java.util.*; class Lobby { static final IoObj Object = new IoObj(); public static void main(String[] args) { //Ioオブジェクトのクローンを作成 IoObj a = Object._clone(); a.setSlot("name", new IoValue<String>("わさお")); a.slot("name").println(); //prints "わさお" //aのクローンを作成して、スロット追加 IoObj aa = a._clone(); aa.setSlot("age", new IoValue<Integer>(10)); aa.slot("name").println(); //prints "わさお" aa.slot("age").println(); //prints "10" //親オブジェクトのスロットを勝手に変更 a.setSlot("name", new IoValue<String>("わさわさ")); aa.slot("name").println(); //prints "わさわさ" //子オブジェクトに同名のスロットを追加 aa.setSlot("name", new IoValue<String>("わさこ")); aa.slot("name").println(); //prints "わさこ" } } class IoObj { /** slot */ final Map<String, IoObj> slot = new HashMap<String, IoObj>(); /** protos */ final List<IoObj> protos = new ArrayList<IoObj>(); /** このオブジェクトをprotosに持つ、新たなIoオブジェクトを作成して返却。*/ IoObj _clone() { return new IoObj().appendProto(this); } /** 指定したスロットに格納されるIoオブジェクトを返却。*/ IoObj slot(String name) { IoObj ret = recursiveLookup(name); if (ret != null) return ret; throw new RuntimeException("this does not respond to '"+name+"'"); } /** 再帰的にスロットを検査する。 */ private IoObj recursiveLookup(String name) { if (slot.containsKey(name)) return slot.get(name); for (IoObj proto : protos) if (proto.recursiveLookup(name) != null) return proto.recursiveLookup(name); return null; } /** 指定したスロットに、指定した値をセット。スロットがなければ作成する。 */ IoObj setSlot(String name, IoObj value) { slot.put(name, value); return value; } /** 親オブジェクトを追加する。 */ IoObj appendProto(IoObj proto) { protos.add(proto); return this; } void println() {System.out.println(this);} @Override public String toString() {return protos+":"+slot;} } class IoValue<T> extends IoObj { final T value; IoValue(T value) {this.value = value;} @Override public String toString() {return String.valueOf(value);} }