11
\$\begingroup\$

I have implemented a Mammal class hierarchy in Java. Is it an intelligent approach, with respect to decomposition, locality and procedural abstraction?

package Hierarchies;

public class Mammals {

    public Mammals(){           
    }

    public void giveMilk(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of produce Milk
        System.out.println("Produce milk to feed their babies.");
    }

    public void haveHair(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Have Hair
        System.out.println("Have hair on their bodies.");
    }       
}


public class Cats extends Mammals{

    public Cats(){          
    }

    public void Sounds(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Sound
    System.out.println("Meow Meow Meow!!!.");   
    }
    public void Diet(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Diet
        System.out.println("Cats are Carnivores.");
    }    
}


public class Elephants extends Mammals {

    public Elephants(){         
    }

    public void Trunk(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Have Trunk
        System.out.println("Have Trunk.It functions for grasping, breathing, feeding, dusting, smelling, drinking.");
    }

    public void Diet(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Diet
        System.out.println("Elephants are Herbivorous.");
    }           
}


public class Dogs extends Mammals {

    public Dogs(){          
    }

    public void Bark(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Bark
    System.out.println("Woo Woo!!!.");  
    }
    public void Diet(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of Diet
        System.out.println("Dogs are Omnivores.");
    }    
}


public class Sporting extends Dogs {

    public Sporting(){          
    }

    public void Race(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of purpose for which they used
        System.out.println("Used For Reacing Purposes.");
    }    
}


public class Working extends Dogs {

    public Working(){           
    }

    public void work(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of work they done
        System.out.println("Learns and performs tasks to assist and entertain its human companions.");
    }    
}


public class Pet extends Dogs {


    public Pet(){           
    }

    public void Work(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of work they done
        System.out.println(" Commonly provide their owners physical and emotional benefits.");
    }
}


public class Hunting extends Dogs {

    public Hunting(){                       
    }

    public void Work(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message for their work
        System.out.println(" Hunting dog refers to a canine that hunts with or for humans.");
    }
}


public class WolfHound extends Hunting {

    public WolfHound(){         
    }

    public void Task(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of task they done
        System.out.println(" The breed was originally developed from war hounds to one used for hunting and guarding.");
    }    
}


public class FoxHound extends Hunting {


    public FoxHound(){          
    }

    public void Task(){
        //REQUIRES: nothing
        //MODIFIES: nothing
        //EFFECTS : Display message of task they done
        System.out.println(" A foxhound is a type of large hunting hound bred for strong hunting instincts, great energy, and, like all scent hounds, a keen sense of smell.");

       }
}

Main Method

import java.util.*;

public class Main {

    public static void main(String[] args) {

        Scanner input=new Scanner(System.in);

        Mammals mam= new Mammals();

        Dogs dog= new Dogs();
        Cats cat=new Cats();
        Elephants elep=new Elephants();

        Sporting sport=new Sporting();
        Working work= new Working();
        Pet pet=new Pet();
        Hunting hunt=new Hunting();

        WolfHound wolf=new WolfHound();
        FoxHound fox =new FoxHound();


        System.out.println("Welcome to Mammals Class !!!");
        System.out.println("1-Dogs ");
        System.out.println("2-Cats ");
        System.out.println("3-Elephants ");
        System.out.println("Enter the Number To which Mamamal Class You GO ");
        int choice=input.nextInt();
        switch(choice){
        case 1:
            System.out.println("1- Sporting ");
            System.out.println("2- Working ");
            System.out.println("3- Pet ");
            System.out.println("4- Hunting ");
            int choice2=input.nextInt();
            switch(choice2){
            case 1:
                sport.giveMilk();
                sport.haveHair();
                sport.Bark();
                sport.Diet();
                sport.Race();
                break;
            case 2:
                work.giveMilk();
                work.haveHair();
                work.Bark();
                work.Diet();
                work.work();
                break;
            case 3:
                pet.giveMilk();
                pet.haveHair();
                pet.Bark();
                pet.Diet();
                pet.Work();

                break;
            case 4:
                System.out.println("1- WolfHound ");
                System.out.println("2- FoxHound ");
                int choice3=input.nextInt();
                switch(choice3){
                case 1:
                    wolf.giveMilk();
                    wolf.haveHair();
                    wolf.Bark();
                    wolf.Diet();
                    wolf.Task();
                    wolf.Work();
                    break;
                case 2:

                    fox.giveMilk();
                    fox.haveHair();
                    fox.Bark();
                    fox.Diet();
                    fox.Work();
                    fox.Task();
                    break;
                default:
                    System.out.println("Invalid Choice");
                    break;

                }
                break;
            default:
                System.out.println("Invalid Choice");
                break;

            }
            break;
        case 2:
            cat.giveMilk();
            cat.haveHair();
            cat.Diet();
            cat.Sounds();

            break;
        case 3:
            elep.giveMilk();
            elep.haveHair();
            elep.Diet();
            elep.Trunk();

            break;
            default:
                System.out.println("Invalid Choice");
                break;
        }
    }    
}
\$\endgroup\$
4
  • \$\begingroup\$ could you elaborate a little bit on what you actually want to know about the code? "Is It a Intelligent Approach?" - in respect of what? \$\endgroup\$ Mar 8, 2015 at 11:04
  • \$\begingroup\$ @MarioDavid In Respect to Decomposition,locality, Modifiability and Procedural Abstraction \$\endgroup\$
    – Rauf javid
    Mar 8, 2015 at 11:09
  • 1
    \$\begingroup\$ How is a cat not a pet ? \$\endgroup\$ Mar 8, 2015 at 11:31
  • \$\begingroup\$ @OlivierGrégoire I have not Futher elaborate the Cat Class like Dog Class. \$\endgroup\$
    – Rauf javid
    Mar 8, 2015 at 11:34

2 Answers 2

14
\$\begingroup\$

Summary

  • Use singular for class names.
  • Use inheritance where appropriate.
  • Follow code conventions.
  • Be consistent about grammar.
  • Write short methods.

Use Singular for Class Names

Use a name which represents a single object, not the whole group. I.e. change Dogs to Dog.

An exception are utility classes, i.e. the utility class for arrays is called Arrays, the utility class for collections is called Collections. It's not possible to create objects of utility classes (they prevent it by being a zero element enum or a class with a private constructor).

However, your classes are not utility classes. Therefore, use singular.

Appropriate Inheritance

Inheritance is appropriate where the subclass inherits all or almost all traits of the superclass.

Not every noun is a class!

Nouns aren't always classes, they can also be attributes. Pet is such an example. Both, a dog and a cat can be a pet. In fact, one can have any animal as pet. Pet is much more a description of the relationship between the pet holder and the animal.

In your model, all your classes which describe roles should probably simply be variables, not classes.

Keep in mind that in a language like Java, and most (but not all) programming languages, an object cannot change its class during its lifetime. A dog is a dog is a dog and stays a dog, even if it becomes a pet, goes hunting and so on. It should be one and only one object achieving all these things.

Sometimes it can of course make sense to create classes for roles. You could have a class Pet. But in that case, Pet should not be a subclass of these other classes like class Dog. Instead you should use delegation / composition, like this:

class Pet {
    Animal animal;
}

Then the class Pet describes a role, and that role can be fulfilled by any type of animal.

Prefer composition over inheritance.

This is not always appropriate, but you might be interested in learning what it means. Inheritance is really over-used. And inheritance is, unlike some people think, not at the heart of object-oriented programming languages. There are, in fact, programming languages out there which we happily call object-oriented which do not support this simple "extends"-type of inheritance at all. JavaScript is such an example.

Code Conventions

In Java, the convention is to start method names in lower case. Change Task() to task(), Sounds() to sounds() and so on.

Use Proper and Consistent Grammar

Sometimes you use the normal verb form, i.e. giveMilk(), sometimes you use the third person form, i.e. sounds(). Be consistent. It's common in Java to always use the normal verb form, not the third person form, in code. And in comments, it's common in Java to always use the third person form, except if you directly address the reader.

Short Methods

Your main() method is far too long. Good method sizes are like 3-4 lines, sometimes 5, only in rare situations a bit more.

A method should do only one thing, it should do it well, and it should do it only. (Robert C. Martin)

So, think of how to split the main() method into a bunch of smaller methods.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you so much for your review.What a suggestion i love it.Next time i will kept these things in my mind. \$\endgroup\$
    – Rauf javid
    Mar 9, 2015 at 13:53
  • \$\begingroup\$ Those short methods apply also when creating panel with components using layouts? It's really hard to make them small. \$\endgroup\$ Apr 8, 2015 at 6:28
  • \$\begingroup\$ Yes they do. They do (almost) always and they do (almost) everywhere. I'll check out some of your postings soon to show you how it could be done with shorter, cleaner methods. I've seen you've already put up some nice Swing-related code reviews. \$\endgroup\$ Apr 8, 2015 at 13:11
13
\$\begingroup\$

There's a lot of extending going on here. You should consider using interfaces, especially given the addition of default methods in Java 8. Also, some of your class names are strange:

Sporting extends Dog and Working extends Dog

would likely strike any onlookers as highly unusual. SportsDog and WorkDog would be better as class names but again, rather than limiting yourself through inheritance, my suggestion is that you use interface in their place.

Let's see what that could look like using some of your classes.

A Mammal class makes sense, but you definitely wouldn't want anything to be just a mammal right? If we are to ensure specificity such a class should be abstract. Now, a Dog and Cat class that extend the Mammal class makes sense as well, but a Pet class extending Dog...well many animals can be pets, what if you wanted a cat as a pet? This should be an interface instead!

public interface Domesticable {
  default void provideFriendship() {
    System.out.println("Gives love to owner");
  }
}

I added a default method to illustrate a new feature, but if you're using anything lower than Java 8 you'd only write the method signature without the implementation, and have to Ovverride all interface methods in any implementing classes(Which you can still do in this case, e.g. provideFriendship() for cat could specify "by curling around owner's leg"). Think of interfaces as contracts that a class must keep.

So if you did this your Dog class would look more like:

Class Dog extends Mammal implements Domesticable

and you can do the same for any animal that you want to be available as a pet.

Try to identify where else you could make use of an interface. Mind that unlike Inheritance, which is limited to a single class, you can implement multiple interfaces.

So

Pig extends Mammal implements Domesticable, Comparable, Edible

is perfectly legal.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Not trying to give culinary advice, but isn't a Dog also Edible? \$\endgroup\$ Mar 8, 2015 at 16:55
  • 1
    \$\begingroup\$ @Legato Thank you so much for your Suggestion.I will Implement things you Suggested me. \$\endgroup\$
    – Rauf javid
    Mar 9, 2015 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.