Animal Base Class
public class Animal
{
protected String pig;
protected String dog;
protected String cat;
public void setPig(String pig_)
{
pig=pig_;
}
public void setCat(String cat_)
{
cat=cat_;
}
public void setDog(String dog_)
{
dog=dog_;
}
}
AnimalAction Class
public class AnimalAction extends Animal
{
public AnimalAction(String pig, String cat, String dog)
{
super.pig = pig;
super.cat = cat;
super.dog = dog;
}
}
Would this be the correct way to set protected variables? Is using protected variables the correct way to do this? Is there a more professional OO way to do?
You can use private variables instead of protected. This will be more apt.
You can use the constructor to set the value of the super class.
Edited:
public class Animal{
private String pig;
private String dog;
private String cat;
public Animal(String pig,String dog,String cat){
this.pig=pig;
this.dog=dog;
this.cat=cat;
}
}
public class AnimalAction extends Animal
{
public AnimalAction(String pig, String cat, String dog)
{
super(pig,dog,cat);
}
}
You should be able to use this.pig etc, since you inherited the protected members. You could also actually call the public setPig(...) methods.
There is nothing wrong in using protected member variable and then inherit them in subclass .
But If a developer comes along and subclasses your class they may mess it up because they don't understand it fully. With private members, other than the public interface, they can't see the implementation specific details of how things are being done which gives you the flexibility of changing it later.
By providing protected member variables you are just coupling tight between you subclass and superclass.
The less your member variables can be seen outside the class, the better. I would make the class variables private and make the getters public (or as required) & the setters protected.
There's no need to use the super prefix, or any other prefix, to access protected variables.
BTW - I disagree with Thomas on one point - do not call the setter methods of the superclass in your constructor. Using non-final setters in a constructor may have ugly effects if a subclass overrides them. Then they could be called on an incompletely constructed object. But you should consider making your setters final if you don't mean them to be overridden.
The principle of "design for inheritance or forbid it" is explained in the Effective Java book by Joshua Bloch.
Your example is quite confusing, but it would work. I'll give another example:
// use capitals for classes/interfaces/enums, lower case for methods/fields.
public class Animal
{
protected String name;
protected int numberOfFeet;
public Animal(String name)
{
this.name = name;
}
public void setNumberOfFeet(int numberOfFeet)
{
this.numberOfFeet = numberOfFeet;
}
}
public class Dog extends Animal
{
public Dog()
{
super("dog"); // call the constructor of the super class.
// because Dog extends Animal and numberOfFeet is protected, numberOfFeet becomes part of "this" class.
this.numberOfFeet = 4;
}
}
//Now you can create instances of Animal like:
Animal bird = new Animal("bird");
bird.setNumberOfFeet(2);
//Or use Dog to create an animal "dog" with 4 feet.
Animal dog = new Dog();
//after an accident
dog.setNumberOfFeet(3);
Related
So say, for the purposes of illustration that I have an abstract class Animal, and every Animal has a numberOfLegs.
Dog extends Animal and all dogs have a numberOfLegs of 4.
Is it possible to make numberOfLegs...
Static
Required (everything that extends Animal has to define numberOfLegs, or there is some default value)
Accessible from Animal (this one I'm not as concerned about, but if say the method walk() was called from Dog, could Animal view the number of legs without having to pass an extra value?)
Sorry if this is a strange question, and yes, I understand that I could do this easily in other ways, such as making it an instance variable instead of static, but I'm just kind of curious if there's a better way.
Neither static variables or instance variables participate in polymorphism. Just declare an abstract method, e.g. int getNumberOfLegs(), in the abstract class. Your Dog class could be:
class Dog extends Animal {
private static final int NUMBER_OF_LEGS = 4;
public int getNumberOfLegs () {
return NUMBER_OF_LEGS;
}
}
Is it possible to make numberOfLegs: Static
This would make every instance of a class that extends Animal have the same numberOfLegs. See: here for an explanation.
public abstract class Animal
{
private static int NUMBER_OF_LEGS = 4;
}
Is it possible to make numberOfLegs: Required
Yes, you just have to make a property in the abstract class and initialise it in the constructor.
public abstract class Animal
{
private int numberOfLegs;
public int getNumberOfLegs()
{
return this.numberOfLegs;
}
public Animal(int numberOfLegs)
{
this.numberOfLegs = numberOfLegs;
}
}
public class Zebra extends Animal
{
public Animal(int numberOfLegs)
{
super(numberOfLegs);
}
}
everything that extends Animal has to define numberOfLegs, or there is some default value
Furthermore, if you wanted a default value for number of legs, you could inlcude a constructor for Animal without a numberOfLegs parameter and set it to a value, say 4.
public abstract class Animal
{
private int numberOfLegs;
public Animal()
{
this.numberOfLegs = 4;
}
}
Is it possible to make numberOfLegs: Accessible from Animal
Yes, you can call the method (if it's abstract in the Animal class) from any object that extends Animal
Zebra z = new Zebra(4);
System.out.println(z.getNumberOfLegs());
I have a parent class:
public class Animal {
public Animal(String name, AnimalTypeEnum type) {
}
}
I have lots (in the case that has caused me to make this over 30) children:
public class Dog extends Animal {
public Dog(String name, AnimalTypeEnum type) {
super(name,type);
}
}
public class Cat extends Animal {
public Cat(String name, AnimalTypeEnum type) {
super(name,type);
}
}
The objects are constructed from many different places in the project (loaded on start up, created at various times in runtime. To "create" an object, I currently use this function (over 30 subclasses in the project, not just 2):
public static Animal create(String name, AnimalTypeEnum type) {
switch(type) {
case DOG:
return new Dog(name, type);
case CAT:
return new Cat(name, type);
}
}
It is important to note that none of the subclasses have any difference in parameters. The reason I'm using subclasses is because they have one or two functions that are overriden.
Say I now wanted to add a parameter for all subclasses, I'd need to:
Add the parameter to the Animal constructor
Add the parameter to the subclass constructors
Add the parameter to the create() function
(also change the parameter wherever the create() function is being called)
Ideally, I'd like to eliminate changing the subclass parameters (none of the subclasses have different parameters) and the create() function from the above process. But if that isn't possible, I'd like to find a better alternative to the create() function. The best solution I've thought of (psuedocode) is:
public Animal(String name, AnimalTypeEnum type) {
if (type == CAT) this.subclass(Cat);
if (type == DOG) this.subclass(Dog);
}
I think the above goes against the principle of class inheritance so I want to be clear that this isn't the solution I am trying to find, just how I imagine a solution could work.
This is a rather trivial issue but I feel that bad programming practices are behind it and I would like to rectify these. My questions would be (incase I haven't properly explained my problem/reasons):
Is inheritance even the ideal way to do this?
Is it possible to eliminate the process of changing the constructor in subclasses in this situation?
Is there anything I can do to remove the create() function, and assign the subclass when constructing Animal?
Thank you.
I think that you wonna use the Factory Pattern, so you have any options for solve your problem #Doleron showed the first one, but you can use this too:
public interface Animal {
public String getName();
}
The implementation Dog
public class Dog implements Animal{
private String name;
public Dog(String name) {
this.name=name;
}
#Override
public String getName() {
return name;
}
}
Cat
public class Cat implements Animal{
private String name;
public Cat(String name) {
this.name=name;
}
#Override
public String getName() {
return name;
}
}
Factory
public class AnimalFactory {
/*
* Some people use static attributs like:
* public static final String DOG ="DOG";
*/
public static Animal creatAnimal(String animal, String name){
if("DOG".equalsIgnoreCase(animal)){
return new Dog(name);
} else if("CAT".equalsIgnoreCase(animal)){
return new Cat(name);
}
return null;
}
}
Main
public static void main(String[] args) {
Animal animal = AnimalFactory.creatAnimal("dog", "pluto");
/*
* if you use static attribut you can call this form
*/
//Animal dog = AnimalFactory.creatAnimal(AnimalFactory.DOG, "pluto");
System.out.println("Name "+animal.getName()+ " class "+animal.getClass().getSimpleName() );
animal = AnimalFactory.creatAnimal("cat", "garfield");
System.out.println("Name "+animal.getName()+ " class "+animal.getClass().getSimpleName() );
}
you can see another example here.
Since you have an enum to identify the instance type, you could avoid the create/switch/if-else approach using a polymorphic enumeration like:
public enum AnimalTypeEnum {
CAT {
public Animal create(String name) {
return new Cat(name);
}
},
DOG {
public Animal create(String name) {
return new Dog(name);
}
},
COW {
public Animal create(String name) {
return new Cow(name);
}
};
abstract Animal create(String name);
}
As everything this approach has pros and cons. Please see if it fits to your requirements.
First of all, the base class Animal should be an abstract class, because you'll never give life to an Animal object but to a more specific type of Animal, i.e Dog, Cat et cetera. In this way, all animals will have some base methods already implemented.However, if some subclass needs to inherit from another class, you should consider Animal as an Interface, because Java doesn't allow multiple inheritance.
For your second question, if I correctly understand, why can't you add a protected member to the base class Animal and initialize it in the Animal costructor? Eventually, if subclasses as a specific value for this parameter, you can set it in the subclasses costructors.
Finally for the create() function in my opinion you should consider the Abstract Factory pattern.
Let's assume I have the following classes:
public class Cat {
private final String noise = "meow";
pulic static void makeNoise(){
System.out.println(noise);
}
}
public class Dog {
private final String noise = "woof";
pulic static void makeNoise(){
System.out.println(noise);
}
}
As you can see, these two classes share pretty much the same code. To remove redundant code, I'd create a parent class like this:
public abstract class Animal {
protected final String noise;
public Animal(String noise) {
this.noise = noise;
}
public void makeNoise() {
System.out.println(noise);
}
}
public class Dog extends Animal{
public Dog(){
super("woof");
}
}
Now unfortunately I'm running into a two problems:
Since make noise of animal can't be static anymore, as the constants
will have to be assigned through the constructor of animal, you will
need to create a cat or dog to get the noise of that animal. Even
though it is a constant.
The method makeNoise() need's to work in the class Animal - which
doens't have a noise per default.
A possible solution would be something along the line like this:
public abstract void makeNoise();
which is neither allowed, nor would it erase the need to copy the code into each and everyone of the children of Animal.
How would you erase the need to have redundant code in the children of animal while keeping the method makeNoise static?
Static methods in Java can't be overridden in subclasses.
If you define a static method in a subclass with the same signature as the static method in the parent class, the method is not overriding the parent method is hiding it. The methods in the parent and the child class has no relation to each other.
In your example, if method static void makeNoise() exists in Animal and any subclass define the method as well, the subclass is just hiding the makeNoise method in Animal.
In your example, the best you can do with static methods is:
public static void makeNoise(String noise) {
System.out.println(noise);
}
And invoke the method this way:
Animal.makeNoise(Cat.NOISE); // A constant NOISE is defined in each subclass
If the method makeNoise is non-static, inheritance could be used to use a different noise in each subclass:
public abstract class Animal {
protected String noise;
protected Animal(String noise) {
this.noise = noise;
}
public void makeNoise() {
System.out.println(noise);
}
}
public class Cat extends Animal{
public static final String NOISE = "meow";
public Cat() {
super(NOISE);
}
}
Why would you represent a real world object behavior with a static method? Each animal has it's own behavior so you want to differentiate between them.
enum AnimalBehavior {
MEOW, WOOF, ROAR
}
You could use an enum which contains every animal behavior.
Also consider the following situation: A wolf keeps howling during a full moon night. He keeps doing it until he gets exhausted. You want to track a bar which indicates the level of energy your wolf has.
private int energy = 100;
public static void wolfHowl() {
System.out.println(AnimalBehavior.ROAR);
energy = energy - 10;
}
This won't work technically because you're using static methods.. so keep in mind how you design your stuff since that wolf could actually howl without getting tired until someone gets really pissed off.
Is there a point to using interface types in implementations, or should you only use them as part of the public interface of a class or interface?
Example (Java):
public class SomeClass {
// Declare list as..
private List<Object> list = new ArrayList<Object>();
// or...
private ArrayList<Object> list = new ArrayList<Object>();
// Does it matter which way list is declared if it's part
// of the private implementation?
// This parameter should be the most general interface type
// allowed because it's public-facing.
public void someMethod(List<Object> list) {
// ...
}
}
By defining them as abstract as possible, you're hiding implementation details. Should you ever wish to use a different subclass from List<T> instead of ArrayList<T>, then you can do so without breaking code everywhere.
Always make it as abstract as possible while still having the methods available that you need. That way your implementation is as flexible as possible.
For example, I am a person with a pet. Right now I have a cat, but what if I get on a vacation to Africa and happen to see a very awesome elephant? My cat will starve because nobody gave her food and I will put the elephant in my pocket back to Belgium. If I were to define it as a cat, I would have to change my entire class. Instead, I define it as an animal.
public class Person {
String name;
Animal pet;
// Getters & Setters + Constructor
}
public abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Cat extends Animal {
public Cat() { super("Cat")); }
}
public class Elephant extends Animal {
public Elephant() { super("Elephant")); }
}
public class Lion extends Animal {
public Lion() { super("Lion")); }
}
So when I make a new Person:
Person bestPersonInTheWorld = new Person();
bestPersonInTheWorld.setName("Jeroen");
bestPersonInTheWorld.setPet(new Cat());
I can simply kill the cat
bestPersonInTheWorld.dontFeedForTwoWeeks();
And I put my Elephant in the yard:
bestPersonInTheWorld.setPet(new Elephant());
Nothing has to be changed when it comes to implementation.
Good day!
I am reviewing the Java OO concept.
And wrote the following codes:
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.eat();
dog.sleep();
}
}
abstract public class Animal {
private int age;
public Animal (){
age = 1;
}
public Animal (int age){ //How can I call this constructor?
this.age = age;
}
public void eat(){
System.out.println("Eat");
}
abstract public void sleep();
}
abstract public class Canine extends Animal{
abstract public void roam();
}
public interface Pet {
public String petName = null; //i want the pets to have a variable petName.
public void trick();
}
public class Dog extends Canine implements Pet{
public void roam(){
System.out.println("roam");
};
public void sleep(){
System.out.println("sleep");
};
public void eat(){
System.out.println("Eat Dog");
};
public void trick(){
System.out.println("trick");
}
}
I have several questions as follows:
How can I call the Animal Overloaded constructor?
How can I use the variable petName in the PET Interface?
Am I doing the concept of OO correctly? What rules am I violating?
Thank you in advance.
Subclasses will call the super constructor from within their own constructor using super(...) as the first line!
Interfaces cannot have variables or state - only methods!
You have a sound concept, but your code would not compile (because of item 2 above).
Some solutions:
public interface Pet {
String getName();
void trick();
}
Now the Dog class (or any class that implements Pet) will have to implement Pet.getName(). Give the Dog class a field of type String called 'name' and return it from Dog.getName().
public abstract class Canine extends Animal {
public Canine(int age) {
super(age); // pass the age parameter up to Animal
}
...
}
public class Dog extends Canine implements Pet {
private final String name;
public Dog(String name,int age) {
super(age); // call the age constructor
this.name=name;
}
public String getName() { return name; }
... rest of class ...
}
Each subclass (esp. the abstract ones) will need to provide matching constructors for all parent class constructors you want to call! (So I added the age parameter to the Canine constructor so that Dog could pass an age argument to it.
check out this ,it might help you,
http://www.roseindia.net/java/beginners/constructoroverloading.shtml
http://www.jchq.net/certkey/0602certkey.htm
Calling either constructor is calling an overloaded constructor: both constructors use the same name. To call the constructor that takes an int, call dog = new Dog(1);.
The class Dog implements Pet, so it will have a public field petName (is it super.petName?).
I don't see any fundamental errors.
1) you can call argumented contructor as" this(20);"
Example of explicit this constructor call
public class Point {
int mx;
int my;
//============ Constructor
public Point(int x, int y) {
mx = x;
my = y;
}
//============ Parameterless default constructor
public Point() {
this(0, 0); // Calls other constructor.
}
. . .
}super(...) - The superclass (parent) constructor
An object has the fields of its own class plus all fields of its parent class, grandparent class, all the way up to the root class Object. It's necessary to initialize all fields, therefore all constructors must be called! The Java compiler automatically inserts the necessary constructor calls in the process of constructor chaining, or you can do it explicitly.
The Java compiler inserts a call to the parent constructor (super) if you don't have a constructor call as the first statement of you constructor. The following is the equivalent of the constuctor above.
//============ Constructor (same as in above example)
public Point(int x, int y) {
super(); // Automatically done if you don't call constructor here.
m_x = x;
m_y = y;
}Why you might want to call super explicitly
Normally, you won't need to call the constructor for your parent class because it's automatically generated, but there are two cases where this is necessary.
You want to call a parent constructor which has parameters (the automatically generated super constructor call has no parameters).
There is no parameterless parent constructor because only constructors with parameters are defined in the parent class.
A call to the parent constructor is super(); in your case it would be super(12); for example. Note that a call to a constructor (either this() or super() must be the first statement. Note that you can only go up one level, so to call the constructor in Animal, you'd have to code that into Canine and not Dog.
public Dog(int age)
{
super(age); //this will invoke Canine's overloaded constructor
}
//You must now provide the overloaded constructor in Canine which invokes
//the overloaded constructor in Animal
public Canine(int age)
{
super(age); //this will invoke Animal's overloaded constructor
}
You may access the value of Pet.petName as, well, Pet.petName. This is because Interfaces can only have methods (which are implicitly public) and constants (which are implicitly public static final). You could use this.petName but it's pointless (and potentially confusing). You cannot set the value of petName anywhere else, ever since it's final, even if you don't declare it to be.
However in this case, declaring the name as part of the interface doesn't make sense since it's not constant. It should be a part of some abstract or concrete class so that it can be set per instance of Pet. You should instead define a getter (and maybe a setter) for Pet -
public String getName();
public String setName(String name);
these will force implementing classes to provide some sort of implementation to get and set the name for a Pet without enforcing how that name is stored inside of that class.
How can I call the Animal Overloaded constructor?
You need to chain it.
abstract public class Canine extends Animal{
public Canine(int age) {
super(age);
}
// ...
}
and
public class Dog extends Canine implements Pet{
public Dog(int age) {
super(age);
}
//...
}
How can I use the variable petName in the PET Interface?
Pet.petName. If a class implements such an interface, then the class can refer to those constants without a qualifying class name like this: petName
Am I doing the concept of OO correctly? What rules am I violating?
Interface constants