首页 > 解决方案 > 对新的对应对象使用 Java 多态性(StringBuffer 或 StringBuilder)

问题描述

实际上,我想使用 JAVA 多态性来设计一个函数,它可以为我返回一个 StringBuffer 或 StringBuilder 取决于不同的场景。我的错误代码是

public class Builder{
    private boolean threadSafe;
    public Builder(boolean threadSafe) {
        this.threadSafe = threadSafe;
}
    public String buildMsg(String name, int age) {
       AbstractStringBuilder asb;
       asb = threadSafe ? new StringBuffer() : new StringBuilder();
       return asb.append("name: ").append(name).append(", age: ").append(age).toString();
}
}

代码无法编译。错误消息是“java.lang.AbstractStringBuilder”在“java.lang”中不公开。无法从外部包访问。所以我尝试了另一种方法,使用 Appendable 而不是 AbstractStringBuilder,它仍然不起作用。直到,我写这样的代码:

public class Builder{
    private boolean threadSafe;
    public Builder(boolean threadSafe) {
        this.threadSafe = threadSafe;
}
    public String buildMsg(String name, int age) {
       if (threadSafe) {
        StringBuffer sb = new StringBuffer();
        return sb.append("name: ").append(name).append(", age: ").append(age).toString();
    } else {
        StringBuilder sb = new StringBuilder();
        return sb.append("name: ").append(name).append(", age: ").append(age).toString();
    }
}
}

代码显然是多余的。那么如何使用多态来修复我的代码。(我的英文不是很好,希望你能理解)

标签: java

解决方案


我会建议你做

public String buildMsg(String name, int age) {
    StringBuilder sb = new StringBuilder();
    sb = sb
        .append("name: ")
        .append(name)
        .append(", age: ")
        .append(age);
    return sb.toString();
}

因为在这段代码中没有关于多线程的问题。这也正是这StringBuilder门课的用途。

您应该使用StringBufferif 多个线程可以访问同一个StringBuffer对象,但是由于您创建了对象并最终丢失了对它的引用,因此没有其他线程可以访问该对象。


但是,要回答标题中的问题。如果您有两种类型都实现了该方法Foo但没有通用接口,例如:

public class A {
    public Res Foo(Args args) { ... }
}

public class B {
    public Res Foo(Args args) { ... }
}

然后你总是需要一些大小写来区分Foo. 但是您可以为这两种类型实现 Adapter 或 Wrapper 类型,例如:

public abstract WrapperBase {
    public abstract Res Foo(Args args);

    public static WrapperBase Wrap(A a) {
        return new AWrapper(a);
    }
    public static WrapperBase Wrap(B b) {
        return new BWrapper(b);
    }
    // or
    public static WrapperBase Wrap(Object obj) {
        if (obj instanceof A) {
            return new AWrapper((A)obj);
        } else if (obj instanceof B) {
            return new AWrapper((B)obj);
        } else {
            throw new Exception("Can not be wrapped");
        }
    }
}

class AWrapper extends WrapperBase {
    private A a;
    public AWrapper(A a) { this.a = a; }

    @override
    public Res Foo(Args args) { return a.Foo(args); }
}

class BWrapper extends WrapperBase {
    private B b;
    public BWrapper(B b) { this.b = b; }

    @override
    public Res Foo(Args args) { return b.Foo(args); }
}

这样做的缺点是,如果您有大量的方法要结束,这可能会失控。


推荐阅读