Home > Enterprise >  Subclass inherit superclass and add attributes
Subclass inherit superclass and add attributes

Time:03-19

I have two classes that looks like this

public class Animal {
    public Leg leg;
}
public class Leg {
    public Toe toe;
}

Now, I would like to have a new class called Dog to extend class animal and I would like to add Hair on the class Leg. How to extend the class to make it work?

CodePudding user response:

Imagine that you have a class A and you want to extend a class B of class A, Vois l'exemple suivante :

class A {
    String a = "Hello world";
}



class B extends A {
    void m () {
        System.out.println (a);
    }
}

Class B will have access to all the attributes of class A.

CodePudding user response:

Just create your class dog and make it extends the Animal class:

public class Animal {
    public Leg leg;
}

public class Dog extends Animal {
    // dog have also leg from superclass
    //add dog attributes here
}

CodePudding user response:

Contrary to the suggestion in the comments, this problem should not be solved through inheritance. Yes, even implementing an interface is consider "soft" inheritance and will not work without incurring in unnecessary, "dangerous" modifications to existing code. A class should not extend another simply to gain access to some a dependency contained in another class. I know that it sounds confusing. I would like to share this Stack Overflow answer where I explain and illustrate in detail the concept of Dependency Injection; which is what you need to solve this problem.

In your example, the Animal class possesses an attribute Leg that doesn't contain "hair". Along comes a new class Dog that needs a different kind of Leg that contains "hair" instead of "toes". Therefore, this is an incorrect use of inheritance. What you need to do instead is inject the "hairy-leg" behavior to the already existing Animal class rather than create a new class only to exhibit a different behavior. For example:

public class Animal {
    Behavior behavior;
    public void addBehavior(Behavior behavior) {
        this.behavior = behavior;
    }

    public void displayBehavior() {
        behavior.wiggle();
    }
}

You could create an entire family of "behaviors" that could be injected to a particular animal instance. For this example, I will create only two behaviors.

public interface Behavior {
    void wiggle();
}
public class HairyLegBehavior implements Behavior {
    @Override
    public void wiggle() {
        System.out.println("The wind is wiggling the hair on my legs");
    }
}

public class ToeBehavior implements Behavior {
    @Override
    public void wiggle() {
        System.out.println("I'm wiggling my toes");
    }
}

Then, you simply "inject" the desired behavior to each instance.

Animal dog = new Animal();
Animal man = new Animal();
dog.addBehavior(new HairyLegBehavior());
man.addBehavior(new ToeBehavior());
dog.displayBehavior();
man.displayBehavior();

Notice that this approach accomplishes the same goal without the need of unnecessary inheritance chains. Other benefits of this approach:

  1. Observes the Open/Close principle: Dependency Injection when done properly, extends the capabilities of your code without the need to modify existing capabilities. In the OP's example, the requirement of the Dog class would have needed modifying the Leg class to allow adding "hair" to it. This could impact the existing Animal class, which could be undesirable. This change would require more testing of Animal to ensure the change would not interfere with any existing functions (to name one negative aspect of this change).
  2. Coding to interfaces: Making Behavior an interface, allows the code to adopt new behavior seamlessly. In the linked example, I mentioned how games like Apex Legends and Skyrim have this concept of "skins", where you can add attributes to characters on the fly. Although I do not know for certain how this was implemented, it seems this is done thru a common interface using a "Strategy" for applying overlays to the characters by EXPANDING the "skins" rather than creating new characters with different attributes.

In theory, you could have a set of behaviors of a mapping of behaviors to the Animal class to inject each instance with different types of behaviors. For example: eating behavior, walking behavior, sound behavior, sleep behavior, etc.

In conclusion, this is why some of you have heard the following expression or idea: Prefer composition over inheritance.

  • Related