【问题标题】:Inheriting from two Java classes从两个 Java 类继承
【发布时间】:2011-10-01 14:09:43
【问题描述】:

我知道 Java 禁止从多个类继承并允许实现任意数量的接口。然而,虽然接口有利于多态性,但它们不能包含其子类可能想要共享的任何实际代码。如果我有两个不同的超类,它们具有我想在我的子类中使用的共享代码怎么办?

示例:在我的程序中,有两个超类,一个与 HashMaps 一起使用,一个与 Strings 一起使用,它们都有直接的子类,一切都很好。但是现在我有第三个需要两个超类的共享功能,但它只能扩展一个。有没有一种简单的方法可以重新设计这个类结构而不必复制大量代码?

【问题讨论】:

    标签: java inheritance polymorphism multiple-inheritance superclass


    【解决方案1】:

    使用委托而不是继承:

    public class Third implements FirstInterface, SecondInterface {
        private First first;
        private Second second;
    
        public void foo() {
            first.foo();
        }
    
        public String bar() {
            return second.bar();
        }
    }
    

    【讨论】:

      【解决方案2】:

      我见过

      1. 从两个超类中提取接口
      2. 创建一个实现接口的类,然后将所有调用委托给实际对象

        public interface IFirst { public void foo(); }
        
        public interface ISecond { public void bar(); }
        
        public class Third implements IFirst, ISecond {
            private IFirst first;
            private ISecond second;
        
            public Third(IFirst first, ISecond second) {
                this.first = first;
                this.second = second;
            }
        
            @Override
            public void foo() {
                first.foo();
            }
            @Override
            public String bar() {
                return second.bar();
            }
        }
        

      不会让您访问类层次结构中的受保护成员。如果那是您正在寻找的东西,那么您在 Java 中就不走运了。但是,这将允许您以多态方式将此对象称为 IFirst 和 ISecond。因此,您将能够在需要两种类型之一的外部代码中访问它。

      注意:我的名字是从 JB 那里偷来的。

      【讨论】:

        【解决方案3】:

        使用组合——基本上让你的新类扩展其中一个类并在新类中拥有一个超类 2 类型的成员变量。或者你可以全力以赴并在新类上使用组合并拥有其中class1和class2类型成员

        【讨论】:

          【解决方案4】:

          我质疑任何在管理哈希图的类与管理字符串的类之间存在如此多的相互依赖性的设计。但要直接回答您的问题,您可以将您的第三个类设为 Facade 来包装您的两个超类的实例,然后将其方法委托给这些类。

          【讨论】:

            【解决方案5】:

            解决这个问题的一种方法是支持组合而不是继承。如果您可以设计当前想要扩展的两个类,以便它们可以用作新类的成员,那么您应该具有所需的灵活性。而不是

            class MyClass extends MapBehavior, StringBehavior { ... }
            

            试试

            class MyClass {
                MapBehavior mb;
                StringBehavior sb;
                ...
            }
            

            【讨论】:

            • 与我的其他评论相同的问题 - 第二个代码块中的 MyClass 不是子类化(或实现)任何东西 - 这里根本没有继承。
            • 公平点。我将放弃编辑我的帖子,因为 Ryan Gross 已经发布了一个类似的解决多态性问题的 sn-p。
            猜你喜欢
            • 2012-11-28
            • 2011-09-04
            • 2010-09-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-27
            • 2015-04-09
            相关资源
            最近更新 更多