【问题标题】:Can I make a derived class inherit a derived member from its base class in Java?我可以让派生类从 Java 中的基类继承派生成员吗?
【发布时间】:2010-05-11 18:46:45
【问题描述】:

我的代码如下所示:

public class A
{
    public void doStuff()
    {
        System.out.print("Stuff successfully done");
    }
}

public class B extends A
{
    public void doStuff()
    {
        System.out.print("Stuff successfully done, but in a different way");
    }

    public void doMoreStuff()
    {

        System.out.print("More advanced stuff successully done");
    }
}

public class AWrapper
{
    public A member;

    public AWrapper(A member)
    {
        this.member = member;
    }

    public void doStuffWithMember()
    {
        a.doStuff();
    }
}

public class BWrapper extends AWrapper
{
    public B member;

    public BWrapper(B member)
    {
        super(member);         //Pointer to member stored in two places:
        this.member = member;  //Not great if one changes, but the other does not

    }

    public void doStuffWithMember()
    {
        member.doMoreStuff();
    }
}

但是,此代码存在问题。我在两个地方存储了对该成员的引用,但是如果一个更改而另一个没有更改,则可能会出现问题。我知道在 Java 中,继承的方法可以将其返回类型(可能还有参数,但我不确定)缩小到派生类。字段也一样吗?

【问题讨论】:

    标签: java class inheritance


    【解决方案1】:

    您可以使用泛型更好地完成此任务。

    public class AWrapper<T extends A>
    {
        public T member;
        public AWrapper(T member)
        {
            this.member = member;
        }
    
        public void doStuffWithMember()
        {
            a.doStuff();
        }
    }    
    
    public class BWrapper extends Wrapper<B>
    {
        public BWrapper(B member)
        {
            super(member);
        }
    
        public void doStuffWithMember()
        {
            member.doMoreStuff();
        }
    }
    

    子类包装器指定 B 的类型这一事实允许您在 BWrapper 中访问 B 的函数,而无需存储额外的引用。

    【讨论】:

    • 不一定。您可以根据需要将包装器的层数通用化,但如果您正在执行这种编码,您可能会错误地建模域。
    • 抱歉,我对过去的经验感到困惑,因为我不想将二级类通用化以解决可读性问题。是的,愿意让BWrapper 通用它会正常工作。
    • 这个语法是什么意思? public &lt;T&gt; class?我只见过类型参数之后标识符
    • @Eric 我将泛型类型的静态方法声明的语法与类声明格式混淆了。编辑修复。
    • 是的,但我仍然在 SO 的其他地方看到过这种语法。它是否合适,还是只是一个常见的错误?
    【解决方案2】:

    在您的班级BWrapper 中,您必须删除public B member; 行。并在doMoreStuffWithMember() 方法中将行替换为:

    ((B) member).doMoreStuff();
    

    【讨论】:

    • @Jherico:但在这种情况下,您确定它是B 的一个实例。
    • 您无法确定此处所写的内容,因为AWrapper.memberpublic 并且可以设置为非B 实例。如果属性是protected,您甚至都不安全,因为BWrapper 的某些子类可以设置该属性。
    猜你喜欢
    • 2012-10-29
    • 2018-11-30
    • 2017-04-14
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多