代码之家  ›  专栏  ›  技术社区  ›  voodoogiant

实例化另一个对象

  •  3
  • voodoogiant  · 技术社区  · 14 年前

    有很多属性,比如getColor。然后我可以做第二个物体 (可能属于同一类)行为类似于对象的 除非它的一个值被特别地改变了(也没有改变)。

    a = new Foo()
    b = new FooWhichRefersToAnotherFoo(a)
    
    a.getColor() # returns blue
    b.getColor() # returns blue
    a.setColor(red)
    b.getColor() # returns red
    b.setColor(pink)
    b.getColor() # returns pink
    a.getColor() # returns red (unchanged)
    b.deleteChangeToColor()
    b.getColor() # returns red as it is now pointing back to a
    

    我会假设它是某种树层次结构 c类 指向 指向 ,对象将在链上工作到第一个指定值或原始未实现对象的默认值。

    这样的模式是否存在类似于Java的工作模式?我希望第一个类是一个类,第二个是一个继承类,它跟踪它实例化的类,如果没有设置它自己的属性,则查询父对象。

    我想我可以在我创建的每个类中创建一个单独的类

    class Foo {
      Color color = new Color("red");
      Color getColor() { color }
    }
    
    class FooInstance extends Foo {
      Foo parent = null;
    
      FooInstance(Foo parent) {
        this.parent = parent;
      }
    
      Color getColor() {
        if (color == null) return parent.getColor();
        else return color;
      }
    }
    

    但是想确保没有像使用javabeans之类的更简单的机制。继承的一个问题是它暴露了父类的所有方法,而我可能想指定子类中实际可用的方法,所以可能只是一个单独的类?

    4 回复  |  直到 14 年前
        1
  •  1
  •   drekka    14 年前

    我读了你的文章好几遍了,有些东西仍然让我困惑。例如,在您的a/b/c示例中,您谈论的行为是相同的,除非值不同。我认为你需要把行为和陈述的概念分开。行为是一个类将要做的事情,状态是其属性的值。阶级的行为,如果经常依赖于国家,即:

    Color getColor() {
        if (color == null) return parent.getColor();
        else return color;
    }
    

    class Foo {
        Foo parent = null;
        Color color;
    
        Foo(Foo parent) {
            this.parent = parent;
        }
    
        Color getColor() {
            //If there is no parent we have to return color regardless.
            if (parent == null) {
                return color;
            }
    
            // If there is a parent we can choose which to return.
            return color == null ? parent.getColor() : color;
        }
    
        void setColor(Color color) {
            this.color = color;
        }
    }
    

    除非您需要与FooInstance不同的行为,否则可以对单个类执行所需的操作。

    我不知道有哪个第三方API提供这种数据结构。但它们可能存在。

        2
  •  1
  •   Mike Clark    14 年前

    feature 属于 java.util.Properties

    package stackoverflow;
    import java.util.Properties;
    
    public class Main {
        static Properties propsBase;
        static Properties propsOverlay;
        static Properties propsOverlayOverlay;
    
        public static void main(String[] args) {
            propsBase = new Properties();
            propsOverlay = new Properties(propsBase);
            propsOverlayOverlay = new Properties(propsOverlay);
    
            propsBase.setProperty("key1", "value1");
            propsBase.setProperty("key2", "value2");
            debugAllProps();
    
            propsOverlay.setProperty("key1", "overlayValue1");
            debugAllProps();
    
            propsOverlayOverlay.setProperty("key1", "overlayOverlayValue1");
            debugAllProps();
    
            propsOverlayOverlay.remove("key1");
            debugAllProps();
    
            propsOverlay.remove("key1");
            debugAllProps();
        }
    
        private static void debugAllProps() {
            printProps("propsBase", propsBase);
            printProps("propsOverlay", propsOverlay);
            printProps("propsOverlayOverlay", propsOverlayOverlay);
            System.out.println("------------------------------------------------");
        }
    
        private static void printProps(String desc, Properties props) {
            System.out.printf("%-25s", desc + " sees:");
            for (String key : props.stringPropertyNames()) {
                System.out.printf(" %s=%s", key, props.getProperty(key));
            }
            System.out.println();
        }
    }
    


    输出:

    propsBase sees:           key2=value2 key1=value1
    propsOverlay sees:        key2=value2 key1=value1
    propsOverlayOverlay sees: key2=value2 key1=value1
    -------------------------------------------------
    propsBase sees:           key2=value2 key1=value1
    propsOverlay sees:        key2=value2 key1=overlayValue1
    propsOverlayOverlay sees: key2=value2 key1=overlayValue1
    -------------------------------------------------
    propsBase sees:           key2=value2 key1=value1
    propsOverlay sees:        key2=value2 key1=overlayValue1
    propsOverlayOverlay sees: key2=value2 key1=overlayOverlayValue1
    -------------------------------------------------
    propsBase sees:           key2=value2 key1=value1
    propsOverlay sees:        key2=value2 key1=overlayValue1
    propsOverlayOverlay sees: key2=value2 key1=overlayValue1
    -------------------------------------------------
    propsBase sees:           key2=value2 key1=value1
    propsOverlay sees:        key2=value2 key1=value1
    propsOverlayOverlay sees: key2=value2 key1=value1
    

    这种方法有一些重要的局限性:

    • java.util.Properties属性 ,您只能存储和检索 String 价值观。

    • 您必须注意只使用由 java.util.Properties属性 Hashtable ,不知道层次结构并忽略它。

    java.util.Properties属性 ,而是使用 Properties 作为灵感的一般方法。你可以把源代码读到 java.util.Properties属性 看着里面 src.zip ,它与JDK一起安装。

    我对收藏的看法是

    • 允许对象键和对象值
    • 可能不会对任何现有的集合进行子类化-主要是为了避免让每个超类方法“层级意识”。 decorate HashMap .
    • 可能会实现一些 java.util
    • 可能支持泛型
        3
  •  0
  •   Kirk Woll    14 年前

    看起来您正在尝试实现类似于CSS的行为——特别是 部分。这并不是一个特别常见的模式,但我以前必须实现这种模式。我不想把类型分成 Foo FooInstance --我将创建一个类,该类将以一般方式处理此模式,可能使用 HashMap

    public class Foo {
        private Foo parent;
        private HashMap<string, Object> propertyValues = new HashMap<string, Object)>();
    
        public Foo() {
        }
    
        public Foo(Foo parent) {
            this.parent = parent;
        }
    
        protected Object getProperty(string propertyName) {
            if (properties.containsKey(propertyName))
                return properties.get(propertyName);
            else if (parent != null)
                return parent.getProperty(propertyName);
            else
                return null;
        }
    
        protected void setProperty(string propertyName, value) {
            properties.put(propertyName, value);
        }
    
        public Color getColor() {
            return (Color)getProperty("color");
        }
    
        public void setColor(Color color) {
            setProperty("color", color);
        }
    }
    
        4
  •  0
  •   ryanbrainard    14 年前

    我只想用装饰图案。这两个类不一定需要相同,但需要实现一个公共接口,并在构造函数中获取另一个,然后让getter移交给包装类,直到其中一个在包装类中被重写。在这个例子中,为了简单起见,我只使用了一个类,但是可以灵活地使用任何颜色。从测试开始:

    import junit.framework.TestCase;
    
    import java.awt.*;
    
    public class CascadingTest extends TestCase {
    
        public void testCascade() throws Exception {
            Colorful a = new Foo();
            a.setColor(Color.RED);
            assertEquals(Color.RED, a.getColor());
    
            Colorful b = new Foo(a);
            assertEquals(Color.RED, b.getColor());
    
            b.setColor(Color.PINK);
            assertEquals(Color.PINK, b.getColor());
    
            b.setColor(null);
            assertEquals(Color.RED, b.getColor());
        }
    }
    

    import java.awt.*;
    
    public interface Colorful {
        Color getColor();
        void setColor(Color color);
    }
    

    import java.awt.*;
    
    public class Foo implements Colorful {
    
        private Color color;
        private Colorful parent;
    
        public Foo() {}
    
        public Foo(Colorful parent) {
            this.parent = parent;
        }
    
        public Color getColor() {
            if (parent != null && this.color == null) {
                return parent.getColor();
            } else {
                return color;
            }
        }
    
        public void setColor(Color color) {
            this.color = color;
        }
    }