简体   繁体   English

Java多重继承问题

[英]Java multiple inheritance issue

I have a question like this : 我有这样一个问题:

Think a scenario like this 考虑这样的情况

public class Animal {

    protected String Name;
    Boolean canWork;

}

public class Dog {

  Enum TailType

}

And I need to have both of this classes attributes in a class of the third level which extends the both classes .. but using interfaces I don't think this can be achieved. 我需要在扩展这两个类的第三级类中都具有这两个类属性,但是使用接口我认为这是无法实现的。 Is it possible to do this using a design pattern or some else method ? 是否可以使用设计模式或其他方法来执行此操作?

Summary : I want to have attributes from two classes to a concrete class 摘要:我希望具有从两个类到一个具体类的属性

You can have Dog extend Animal, then extend Dog by the third class, but unless your 3rd class is Poodle then you may have a problem you don't realize yet. 您可以让Dog扩展Animal,然后再将Dog扩展到第三类,但是除非您的3类是Poodle,否则您可能会遇到尚未意识到的问题。 That being inheritance is only appropriate when the relationship is a modeling criteria, and extending objects only to get their functionality is the wrong approach. 仅当关系是建模标准时才需要继承,而仅扩展对象以获得其功能是错误的方法。 Inheritance should follow the IS-A principle. 继承应遵循IS-A原则。 That being your subclass IS-A base class in modeling terms. 在建模方面,这就是您的子类IS-A基类。 If it doesn't pass that test you are using inheritance when you shouldn't. 如果没有通过该测试,则您应该使用继承。 After all you can use delegation to obtain their functionality. 毕竟,您可以使用委托来获取其功能。 That meaning: 意思是:

public class SomeClass {

    private Dog dog;

    public void bark() {
       dog.bark();  // this is reusing the functionality without extending
    }
}

Now SomeClass can call or invoke methods on Dog without extending it. 现在SomeClass可以在不扩展Dog的情况下调用或调用方法。 Now the downside to this is a reference to Dog can't point to SomeClass, but if SomeClass is-not-a Dog that's probably good. 现在,它的缺点是对Dog的引用不能指向SomeClass,但是如果SomeClass不是-Dog,那可能很好。 However, if you have to allow Dog and SomeClass to share some typing so you can have a reference that points at either Dog or SomeClass then you can create an interface that both share: 但是,如果您必须允许Dog和SomeClass共享某些类型,以便您可以拥有指向Dog或SomeClass的引用,则可以创建一个共享以下内容的接口:

public class SomeClass implements Barkable {
    private Dog dog;

    @Override
    public void bark() {
       dog.bark();
    }
}

public class Dog implements Barkable {

    @Override
    public void bark() {
       System.out.println( "Bark! Bark!" );
    }
}

With delegation/composition and interfaces you DON'T need multiple inheritance. 使用委托/组成和接口,您不需要多重继承。 It's a really simple technique to apply and master and you'll build systems that are much more flexible than relying on inheritance alone. 这是应用和掌握的一种非常简单的技术,您将构建比仅依赖继承要灵活得多的系统。

if you are trying to have just attributes, I think you can use interfaces like: 如果您尝试仅具有属性,我认为您可以使用如下接口:

interface A{
int a = 0;
}
interface B{
int b = 1;
}
class implements A, B{
//can access A.a and B.b
}

But this is not a good approach, interfaces are meant for contracts not just to contain constants (variables in interface are static and final by default) 但这不是一个好方法,接口不仅仅用于包含常量的接口(默认情况下,接口中的变量是静态的和最终的)

For good reasons modern OO languages like Java and C# do not support multiple inheritance. 出于充分的原因,现代的OO语言(如Java和C#)不支持多重继承。

The replacement to use in most cases is the interface: 在大多数情况下使用的替代品是接口:

public Interface NameAndWorkable {
  setName(String name)
  String getName();
  boolean canWork();
  setCanWork(boolean canWork);
}

public Interface TailAnimal {
   TailtypeEnum getTailType();
   setTailType(TailtypeEnum tailtype);
}

public class Animal implements NameAndWorkable {
  private String name;
  private boolean canWork;

  public setName(String name)
  public String getName();
  public boolean canWork();
  public setCanWork(boolean canWork);
}

public class Dog implements TailAnimal {

   private TailTypeEnum tailType;

   public TailtypeEnum getTailType();
   public setTailType(TailtypeEnum tailtype);
}

and now the third object with fullfills both Interfaces 现在,第三个对象完全填充了两个接口

public class WorkingNamedDog implements NameAndWorkable, TailAnimal {

  private String name;
  private boolean canWork;
  private TailTypeEnum tailType;

   // from NameAndWorkable 
   public setName(String name)
   public  String getName();
   public  boolean canWork();
   public  setCanWork(boolean canWork);

  // from TailAnimal
   public TailtypeEnum getTailType();
   public setTailType(TailtypeEnum tailtype);

}

To achieve multiple inheritance, it is necessary to use Interfaces. 要实现多重继承,必须使用接口。 You can either use inheritance by extending these classes on one another like: 您可以通过将这些类彼此扩展来使用继承,例如:

//Your first class
public abstract class Animal{


//It is upto you to use an abstract method inside it. However it is not necessary to do so!
 //define an abstract method inside an abstract class.

}

//Your second class
public class Dog extends Animal{

}

//Your third class

 public class ThirdClass extends Dog{
 //here you can instantiate Dog
 private Dog dogObject = new Dog();

 public void anyMethod(){
      dogObject.anyMethodsThatAreDefinedInClassDogAndAnimal();
      }

 }

Hope this helps!! 希望这可以帮助!!

Dog should be a subclass of Animal . Dog应该是Animal的子类。 Then your third class would be a subclass of Dog . 那么您的第三类将是Dog的子类。 This third class would have the attributes of Dog and Animal . 第三类将具有DogAnimal的属性。

If Dog is not a subclass of Animal then you would need multiple inheritance to achieve what you want. 如果Dog不是Animal的子类,则您需要多重继承才能实现所需的功能。 Since Java does not support multiple inheritance you have to make Dog a subclass of Animal . 由于Java不支持多重继承,因此必须使Dog成为Animal的子类。


Or in case, your two classes are not in same inheritance hierarchy, then you have two options: - 或者,如果您的两个类不在同一继承层次结构中,那么您有两个选择:-

  • Either make them interfaces, and then you can implement both the interfaces. 使其成为接口,然后可以实现这两个接口。
  • Or, use Composition instead of Inheritance , in which case, you would need to have the references to both the classes - Animal and Dog , as attribute in your class. 或者,使用Composition而不是Inheritance ,在这种情况下,您需要将对类AnimalDog的引用作为类中的属性。

Eg: - 例如:-

public class YourClass {
    Animal animal;
    Dog dog;
}

However, it doesn't make sense to have Animal and Dog class, with Dog not being a subclass of Animal . 但是,拥有AnimalDog类没有意义,因为Dog不是Animal的子类。 So, you should change that first, and then you would be able to use inheritance . 因此,您应该先进行更改,然后才能使用inheritance

You can extend one class and have another class as composition like this: 您可以扩展一个类,让另一个类作为组合,如下所示:

public class MyClass extends Dog {
    private Animal animal; // instance of Animal class
    // rest of the code to expose Animal class's attributes as per your need
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM