【问题标题】:Cannot Implement or extend - java无法实现或扩展 - java
【发布时间】:2015-09-11 18:24:52
【问题描述】:

我有一个班级 C 有很多成员(比如 10 个成员)+ 仅在 C 中的成员

我还有两个班级AB 正好有上面提到的10 个成员。 (A和B各自没有这10个成员。这10个成员分布在A和B之间,A和B的其他字段很少)

class C {
    private int member1;
    private String member2;
    private String member3;
    private float member4;
    ...
    private String member10;

    private member11_only_in_C;
    private member12_only_in_C;
    ...
}



class A {
    private String memeber10;
    private float member4;
    private double member6;
    ....
}
class B {
     private int memeber1;
     private String memeber2;
     private String member7;
     ....
 }

所以当我有cObject 时,我需要设置AB 中所有成员的值

aObject.setMember10(cObject.getMember10());
bObject.setMember1(cObject.getMember1());
... and so on for all 10 members

这看起来很糟糕(很长一段时间,如果我向 C、A、B 添加更多成员,我需要为它们编写设置器)。所以我的想法是如果我有 C 类 extend or implement A and B 我可以 cast 它喜欢

 A aObject = (A)cObject;
 B bObject = (B)cObject;

但问题是

  1. Java 不允许多重继承
  2. 我不能将AB 作为接口,因为我需要设置它们的值。 (如果我将它们作为接口,它们的成员将变为final,这意味着我无法更改它们的值)
  3. 我不能扩展一个类并实现另一个类。 (然后我无法设置接口成员的值)

我现在能做什么?

谢谢..

【问题讨论】:

  • 您已经说过ABC 之间的相似之处(它们都有相同的字段),但有什么区别?为什么你需要 3 个类而不是 1 个?
  • A 和 B 的成员在 C 中。C 可以有任何其他字段。
  • 这仍然是糟糕的代码设计。您应该有一个只有公共成员的基类,并使用聚合和继承(或其他一些非基于类的方法)将其他成员合并到 A、B 和 C 中。
  • 正如@ShotgunNinja 所说,正确的设计应该是这样的:如果 C 是自卸卡车,B 可能是卡车,A 可能是机动车辆,所以 A 是 B 的超类B 是 C 的超类。没有什么可以阻止 D 类,比如说汽车也有 A,因为它是超类。您的投射代码仍然可以正常工作。
  • 如果不能改变A、B、C的层次结构,那么你应该考虑将A和B封装在C内部,并路由C的访问器使用A或B来提供信息需要。然而,这可能是草率和过度的,并且可能会降低用户了解其信息来自何处的能力。

标签: java inheritance implements


【解决方案1】:

据我了解,您有两个类 AB,它们都有多个字段,并且您想创建第三个类 C,其中包含 AB 的所有字段。

正如你所指出的,你不能用 Java 中的继承来做到这一点,因为不支持状态的多重继承。

您可以使用合成来做类似的事情。

public final class C {

    private final A a;
    private final B b;

    public C(A a, B b) {
        this.a = a;
        this.b = b;
    }

    ...

    void setMember7(String s) {
        b.setMember7(s);
    }

    String getMember7() {
        return b.getMember7();
    }

    ...
}

我不确定这是一个好主意还是您需要什么。我们需要有关您的用例的更多信息。

编辑

如果AB 有不在C 中的字段,您可以创建一个类A2AC 共有的所有字段和一个类B2 与所有BC 共有的字段,如下所示:

public final class A {

    private final A2 a2;
    // other fields

    public A(A2 a2) { 
        this.a2 = a2;
    }
}

public final class B {

    private final B2 b2;
    // other fields

    public B(B2 b2) {
        this.b2 = b2;
    }
}

public final class C {

    private final A2 a2 = new A2();
    private final B2 b2 = new B2();

    ...

    public void setMember7(String s) {
        b2.setMember7(s);
    }

    public String getMember7() {
        return b2.getMember7();
    }

    ...

    public A getA() {
        return new A(a2);
    }

    public B getB() {
        return new B(b2);
    } 
}

【讨论】:

  • 我已经开始上三门课了。当我有一个 C 类的对象时,我需要填充 A 和 B 的字段
  • 这并不能解决我的问题。还是要所有成员一个一个设置
  • @Ashwin 我已经改变了我的答案。我不知道这是否更好。您可以通过将字段捆绑到一个类中来避免逐个设置字段。
  • @Ashwin 你没有。无论您目前对C 使用的任何方法都不需要更改 - 唯一的区别是它们更改A2B2 的字段,而不是直接更改C 的字段。如果您不想编写 setter,您可以简单地将 A2B2 包的字段设为私有(通常不是一个好主意,但它可以工作)。如果您不想使用组合,并且不想单独传输字段,则必须求助于反射 - 在循环中读取 A 的字段并根据值设置值 a C 实例,但这太可怕了。
【解决方案2】:

我不知道你到底想要什么,但我认为你需要的可以在构造函数中完成

Class A{
 private member1;
 private member10;
 Class A(){
 }
 Class A(C cObject){
  member1 = cObject.getMember1();
  //the rest of member varaibles you want to set
  member10 = cObject.getMember10();
  }
}
Class B{
 private member1;
 private member10;
 Class B(){
 }
 Class B(C cObject){
  member1 = cObject.getMember1();
  //the rest of member varaibles you want to set
  member10 = cObject.getMember10();
  }
}

使用它:-

 B objectB = new B(objectC);
 A objectB = new A(objectC); 

【讨论】:

  • 这并不能解决我的问题。还是要所有成员一个一个设置
猜你喜欢
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多