James Gould
James Gould

Reputation: 4702

Inheriting different booleans from 2 classes

I've built a kennel system that checks dogs into the system using .txt files, allows you to perform a variety of actions such as search, remove, print all etc.

I'm currently using inheritance to add functionality for cats as they share a lot of the same variables (name, favourite food etc).

I'm using a boolean unique to dogs and cats which is "does the dog like bones" for dogs and "can cats share a run" for cats.

I've ran into a problem using inheritance because the two booleans aren't the same (obviously) and use different variables/identifiers in the code (not sure of the correct terminology here, please let me know if possible) and it's throwing errors.

Here's what I have so far

import java.util.ArrayList;

public class Pet {

    protected ArrayList<Owner> originalOwners;
    //private boolean likesBones;
    protected String petName;
    protected String favFood;
    protected int foodPerDay;

    public Pet(String name, ArrayList<Owner> owners, String food, int mealsPerDay) {
        petName = name;
        this.favFood = food;
        this.foodPerDay = mealsPerDay;
        originalOwners = new ArrayList<Owner>();
        for(Owner o: owners){
            Owner copy = new Owner(o.getName(), o.getPhone());
            originalOwners.add(copy);
        }
    }

    public String getName() {
        return petName;
    }

    public void setName(String newName) {
        petName = newName;
    }

    /**
    * Returns a copy of the original owners
    * @return A copy of the original owners as an array
    */
    public Owner[] getOriginalOwners(){
        Owner[] result = new Owner[originalOwners.size()];
        result = originalOwners.toArray(result);
        return result;
    }

    /**
    * How many times a day to feed the dog
    * @param feeds The number of feeds per day
    */
    public void setFeedsPerDay(int feeds){
        foodPerDay = feeds;
    }

    /**
    * The number of feeds per day the dog is fed
    * @return The number of feeds per day
    */
    public int getFeedsPerDay(){
        return foodPerDay;
    }

    /**
    * What's his favourite food?
    * @param food The food he likes
    */
    public void setFavouriteFood(String food){
        favFood = food;
    }

    /**
    * The food the dog likes to eat
    * @return The food 
    */
    public String getFavouriteFood(){
        return favFood;
    }

    /**
    * Note that this only compares equality based on a
    * dog's name.
    * @param The other dog to compare against.
    */
    @Override
    public boolean equals(Object obj) { // Generated by Eclipse to be more robust
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Dog other = (Dog) obj;
        if (petName == null) {
            if (other.petName != null)
                return false;
        } else if (!petName.equals(other.petName))
            return false;
        return true;
    }

    /**
    * A basic implementation to just return all the data in string form
    */
    public String toString() {
        return "Dog name:" + petName + "Original Owner:" + originalOwners + "Favfood:" + favFood
        + "FoodPerDay:" + foodPerDay;
    }

}

The dog class:

import java.util.ArrayList;

public class Dog extends Pet {
    public static boolean likesBones;
    public Dog(String name, ArrayList<Owner> owners, String food, int mealsPerDay, boolean likeBones) {
        super(name, owners, food, mealsPerDay);
        Dog.likesBones = likeBones;
    }

    /**
    * Does the dog like bones?
    * @return true if he does
    */
    public static boolean getLikesBones() {
        return likesBones;
    }
}

The cat class

import java.util.ArrayList;

public class Cat extends Pet {
    public static boolean shareRun;
    public Cat(String name, ArrayList<Owner> owners, String food, int  mealsPerDay, boolean shareRun) {
        super(name, owners, food, mealsPerDay);
        Cat.shareRun = shareRun;
    }

    public boolean getShareRun(boolean doesShare) {
        return shareRun;
    }
}

I can't add in the boolean for both likeBones and shareRun to Pet() because they're from different classes, so if I'm trying to add a dog I get a null point exception (I believe) and vice versa for cats.

My question: how can I support both booleans for cats and dogs in the Pet() class without it throwing an exception?

Please let me know if this question makes sense, I've had some trouble explaining my issue before (new to programming). Thanks in advance guys.

Upvotes: 0

Views: 186

Answers (3)

Robert Moskal
Robert Moskal

Reputation: 22553

Your Cat class is set up almost right with a private shareRun field and public getters and setters. But why does this class also have a public static shareRun field?

Your Dog class should follow the same pattern as Cat with regard to likesBones. Currently, you have it set up as a static property which is wrong.

If you are getting an error if you try to do something like

Pet fido = new Pet();
dodo.setLikesBones(true);

You will get a compiler error, since Pet doesn't declare that method.

You can declare those fields and methods on Pet, but then both cats and dogs have the option of liking bones and being able to share a run.

Use the base class to share common attributes and the child classes to make distinctions.

Does that make sense?

Upvotes: 0

fbelanger
fbelanger

Reputation: 3568

Hey I think you might want to force Dog and Cat to set the boolean declared in Pet. Maybe make an abstract method in Pet, then put it in the Pet constructor.

class abstract Pet {
    ...
    public Pet() {
        ...
        setRandomBoolean();
    }
    ...
    protected abstract void setRandomBoolean();
    ...
}

It is obvious, reading this code, that the property of liking bones (what dog doesn't?) and sharing runs are too abstract and unrelated.

Like BIU said, they should have completely seperate implementations.

Upvotes: 0

BIU
BIU

Reputation: 2430

Because likebones is specific to dogs it should only exist in the Dog class, not the parent Pet class. Likewise shareRun should exist only in the Cat class, not the parent Pet class.

Think about the structure logically. A parent class should contain information used by all its children - the point of it is to allow functionality to be shared. Functionality that is not shared does not belong in a place that is meant to help share functionality.

What you could do if you need functions that use that boolean for any child of Pet would be to define a generic boolean special in the parent and implement functions that use it, and then somewhere else keep track for each type of Pet what its special is - but not knowing your system I'm not sure it's the best for you.

Upvotes: 1

Related Questions