I'm a beginner to java, and I'm having issues creating an object that is a child of a parent class. I can't share source code, because it is for a school project; and I don't want to get dinged for cheating. But, I can write similar code; so that I can gain a fundamental understanding to the concepts that I am not grasping.
Java Environment: Eclipse
When I am attempting to create an child object in my Test class, I'm getting an error (that red symbol in the line numbers).
The error message that I'm receiving is "The constructor Animal(Long, String, Float, String, String) is undefined. Then the suggestions offer two options, modify the Animal constructor to include the child Dog class parameters. Or, create a new Animal constructor with the Animal and child Dog class parameters.
I'm not sure why this is happening. I've double checked and I'm not getting errors at the child constructors; and I'm using "super()". I thought that OOP and Java would automatically create a child object with the matching parameter pattern. Any help would be appreciated.
Parent Class
pubic class Animal {
Long id;
String section;
Float price;
public Animal (Long id, String section, Float price){
this.id = id;
this.section = section;
this.price = price;
}
}
1st Child Class
public class Dog extends Animal {
String name;
String favoriteToy;
public Dog (Long id, String section, Float price, String name, String favoriteToy){
super(id, section, price);
this.name = name;
this.favoriteToy = favoriteToy;
}
}
2nd Child Class
public class Bird extends Animal {
String name;
Integer wingSpan;
public Dog (Long id, String section, Float price, String name, Integer wingSpan){
super(id, section, price);
this.name = name;
this.wingSpan = wingSpan;
}
}
Test Class
public class Test {
public static void main(String[] args) throws java.lang.Exception{
//I get error here
Animal animal1 = new Animal (Long.valueOf(76532), "Canine", 99.95, "Sparky", "tennis ball");
}
}
Your Animal class has exactly one constructor
public Animal (Long id, String section, Float price){
but you're calling a constructor
new Animal (Long.valueOf(76532), "Canine", 99.95, "Sparky", "tennis ball");
This constructor does not exist for Animal. It is exactly what the compiler told you with "The constructor Animal(Long, String, Float, String, String) is undefined". What exists is
public Dog (Long id, String section, Float price, String name, Integer wingSpan){
that is a constructor of your Dog class. You probably want to call that like
new Dog (Long.valueOf(76532), "Canine", 99.95, "Sparky", "tennis ball");
As Dog inherits from Animal, i.e. Dog is an Animal, you can store a Dog reference in a variable of type Animal like
Animal animal1 = new Dog (Long.valueOf(76532), "Canine", 99.95, "Sparky", "tennis ball");
Related
I am new to java and was learning about inheritance and polymorphism.
I have an abstract Pet class and have subclasses Dog and Bird which extend from the Pet parent class.
public abstract class Pet {
private String name;
private int age;
private String color;
public Pet(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public void speak() {
System.out.println("I am a speak method of main class");
}
}
public class Dog extends Pet{
private String numberOfTeeth;
public Dog(String name, int age, String color, String numberOfTeeth) {
super(name, age, color);
this.numberOfTeeth = numberOfTeeth;
}
public String getNumberOfTeeth() {
return numberOfTeeth;
}
public void setNumberOfTeeth(String numberOfTeeth) {
this.numberOfTeeth = numberOfTeeth;
}
public void playFetch() {
System.out.println("dog is playing fetch");
}
}
public class Bird extends Pet{
private int flapsPerSecond;
public Bird(String name, int age, String color, int flapsPerSecond) {
super(name, age, color);
this.flapsPerSecond = flapsPerSecond;
}
public void fly() {
System.out.println("the bird is flying");
}
}
Now I am trying to create a database for the pets objects. The dilemma is that I am not sure if I should create separate tables for the Dog and Bird class or should just have the one single Pet table. In the front end, I am trying to implement functions specific to the type of pet. For example, if the object type is Dog, then create a button that makes a barking sound. And if the object type is Bird, then create a button that makes birds' wings flapping noise. I was thinking of creating a column called 'Species' on the Pet Table and it state whether the Pet is a Dog or a Bird. And when we pull the data from the database, if we see that Species string value is Dog, then create appropriate buttons accordingly.
There are multiple strategies to store polymorphism classes in the database.
Take a look at the Hibernate-ORM docs section 2.11 Inheritence. Those 5 subsections are basically 5 different strategies. Each has trade-offs on query efficiency, data size, etc.
For example, you can put Bird and Dog and Pet:
or in a single table (Pet). This means that the column Pet.flapsPerSecond is null for a dog
or in 3 different tables (Pet, Bird, Dog). This means that loading a dog requires querying both Dog and Pet.
or in 2 tables (Bird, Dog). This mean to query all pets, you need to union results after running the queries.
...
The examples here are just the tip of the icebergs of the trade-offs.
I have the following program:
public class Driver {
public static void main(String[] args) {
Animal dog = new Dog("larry");
dog.speak();
}
}
public abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public abstract void speak();
}
public class Dog extends Animal {
private String name; // is this even needed?
public Dog(String name) {
super(name);
}
#Override
public void speak() {
System.out.println("I am " + name);
}
}
Running this program prints I am null, which is not what I want.
Why doesn't it just use the Animal variable defined name and print out larry?
What is the proper way to do this?
If I remove the name from the Dog class, is it possible to reference the Animal name variable while still keeping it private?
If so, how?
The name variable used in
System.out.println("I am " + name);
is the one defined in the Dog class. It is never set, hence null is printed.
There is no need to define name in both Animal and Dog. My suggestion would be to:
remove name from Dog
change the visibility of name in Animal to protected
If you want to keep the access to name as private, add a "getter" method for name to Animal, thus:
public class Animal {
private String name;
public String getName() { return name; }
}
public class Dog {
#Override
public void speak() {
System.out.println("I am " + getName());
}
}
You don't need the variable name in Dog; it is a separate variable from the one in Animal. The Animal constructor initializes the name in Animal correctly, but the speak method in Dog refers to the uninitialized name variable in Dog; the variable in Dog is the one that is in scope inside the Dog class code. Delete the name variable in Dog to avoid confusion.
But to keep name private in Animal and access it in a subclass, provide a getter method in Animal.
public String getName() { return name; } // or protected
Then you can call it in Dog:
System.out.println("I am " + getName());
Output:
I am larry
This following code gives the output as :
Output:
Animal
Dog
Animal
I'm confused why "a.type" outputs as "Animal" even after the assignment "a=b". Why is it so?
Another observation was when I don't declare variable - "String type" inside Dog class. Then I get the output as :
Output:
Dog
Dog
Dog
My code:
//Parent class
class Animal {
String type;
public Animal(){
this.type= "Animal";
}
}
//Child class
class Dog extends Animal {
String type;
public Dog(){
this.type ="Dog";
}
}
//Main Class To Test
class TestDog{
Animal a = new Animal();
Dog b = new Dog();
Animal c = new Dog();
a = b;
System.out.println(a.type);
System.out.println(b.type);
System.out.println(c.type);
}
First a didactic point. You state in your tile:
What happens when parent class object is assigned child class object?
Please understand that you're assigning a child class object to a parent type variable. This may seem picky, but it's an important distinction and gets to the core of how Java implements OOPs and uses reference variables. Also the parent type might not even be a class, but could be an interface (a "pure" type).
As for your confusion, you're adding a type field to both the parent and the child class. Don't, since fields aren't overridden. Add it to the Parent only. Make it protected or give it getters and setters.
For example:
class Animal {
private String type;
public Animal() {
this.type = "Animal";
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
// Child class
class Dog extends Animal {
String type;
public Dog() {
setType("Dog");
}
}
// Main Class To Test
class TestDog {
public static void main(String[] args) {
Animal a = new Animal();
Dog b = new Dog();
Animal c = new Dog();
a = b;
System.out.println(a.getType());
System.out.println(b.getType());
System.out.println(c.getType());
}
}
I'm doing an exercise on Inheritance and polymorphism, I have 3 seperate clasees, my main class, a super Animal class, and a sub Cat class. I've made overloaded constructors, getters and setters, and toString() methods in both Animal and Cat classes. I think I have the inheritance part down. Now I need to make 2 Animal Object references, both an instance of Cat, example: one a type Siameese with a name Tobbie.
Could anyone give me an example of one of these object references? You can see I've attempted in my Main class there, but I'm not sure if that is correct.
Here are the three different classes I have currently.
public class Hw02 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Animal Siamese = new Cat("Tobbie");
}
}
Here's my Animal Class.
public class Animal {
private String name;
public Animal() {
this("na");
}
public Animal(String name) {
this.name = name;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Animal{"
+ "name="
+ name
+ '}';
}
}
And here is my Cat class.
public class Cat extends Animal {
private String type;
public Cat() {
}
public Cat(String type) {
this.type = type;
}
public Cat(String type, String name) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#Override
public String toString() {
return "Cat{"
+ "type="
+ type
+ '}';
}
}
// in main method
Animal tobbie = new Cat("siamese", "Tobbie")
Animal jackie = new Cat("tomcat", "Jackie")
// in Cat class
public Cat(String type, String name) {
super(name)
this.type = type;
}
A few comments:
It is not proper convention to have the name Siamese; variable names should be "camelCase" (start with a lower-case letter). Compiler will accept it is as you have written, but it is a bad practice.
Your Cat(String type, String name) constructor didn't invoke the proper superclass constructor, thus type was lost; same for the Cat(String type) constructor
I think I would make Animal abstract and its constructors protected. I think it is a bad practice to let clients directly instantiate Animals without specifying what kind of animals they are.
Edit:
Like this:
Animal animal = new Animal("What am I?")
However, I don't consider it a good practice to do this, probably what you want done is better achieved otherwise.
Edit:
Cat toString():
public String toString() {
return super.toString() + " Cat{type=" + type + "}";
}
With the code you have above, this is an example:
Animal animal0 = new Cat("Siamese", "Bob");
Animal animal1 = new Cat("Tomcat", "Frank");
Animal animal2 = new Cat("Tomcat", "George");
Animal animal3 = new Animal("Elephant");
System.out.print(animal0.toString());
System.out.print(animal1.toString());
System.out.print(animal2.toString());
System.out.print(animal3.toString());
Would produce the output:
Cat{type=Siamese}
Cat{type=Tomcat}
Cat{type=Tomcat}
Animal{name=Elephant}
Implement Zoo class (with its test class). Zoo have name and area in meter square. Zoo can have one or more Animals. An Animal has ID, name, Type, Age, gender. We should be able to add new Animals to the Zoo, remove Animals and determine how many animals currently in the zoo.
This is the Zoo class:
import java.util.ArrayList;
public class Zoo {
String name;
String area;
ArrayList<Animal> animals;
static int id;
public Zoo(String name, String area) {
this.name = name;
this.area = area;
}
public void addanimal(animal ann) {
animals.add(id, ann);
id++;
}
}
public class Animal {
String name;
String type;
String age;
String gender;
public Animal(String name, String type, String age, String gender) {
this.name = name;
this.type = type;
this.age = age;
this.gender = gender;
}
}
public class Test {
public static void main(String[] args) {
Zoo nozha = new Zoo("nozha", "100");
Animal lion = new Animal("lion", "male", "20", "fine");
nozha.addanimal(lion);
Znimal tiger = new Animal("tiger", "male", "30", "ssc");
nozha.addanimal(tiger);
System.out.print(Zoo.id);
}
}
First I need help with function (addanimal) because when I print (zoo.id) its not working and I didn't know how to remove animal please help me i am beginner in programming and this is my first time i used ArrayList and I never asked before
You need to initialize the animals variable to something other than its default value, which is null:
private List<Animal> animals = new ArrayList<Animal>();
Then look at the javadoc of java.util.List, and you'll see that it contains methods to add and remove elements, as well as a method which returns its size, and makes thus the id variable completely unnecessary.
Also, notice in the javadoc how ALL the classes start with an uppercase letter, and ALL the methods are spelled in camelCase (like addAnimal() and not like addanimal()). Respect these conventions: they're a very important factor for the readability of your code.
Also, choose the appropriate type for your variables. An area, in meter square, should be an int or a float or a double, but not a String.
First i need help with function (addanimal) because when i print (zoo.id)
Basing from your code it seems that zoo.id would return the size of ArrayList<animals> why use the size of the said list instead animals.size() or by rule of encapsulation, getAnimals().size(). This may return a NullPointerException, so intialize ArrayList<animals> with a emptyarraylist`
In removing a said animal in the list, you better go for animals.remove(Animal ann).
In updating, check for if animals.contains(Animal ann) is true, via ID or hashCode then check what index is ann in the list then update ann by animals.set(<index>, ann)
Zoo.java:
import java.util.ArrayList;
public class Zoo {
String name;
double area;
int sizeOfZoo = 0;
ArrayList<Animal> animals = new ArrayList<Animal>();
public Zoo(String name, double area) {
this.name = name;
this.area = area;
}
public void addAnimal(Animal ann) {
animals.add(ann);
}
public int getSizeOfZoo() {
return animals.size();
}
}
Animal.java
public class Animal {
String name;
String type;
String age;
String gender;
public Animal(String name, String type, String age, String gender) {
this.name = name;
this.type = type;
this.age = age;
this.gender = gender;
}
}
Test.java
public class Test {
public static void main(String[] args) {
Zoo nozha = new Zoo("nozha", 100);
Animal lion = new Animal("lion","fine","20","male");
nozha.addAnimal(lion);
Animal tiger = new Animal("tiger","ssc","30","female");
nozha.addAnimal(tiger);
System.out.println("Number of animals in zoo: " + nozha.getSizeOfZoo());
}
}
I threw in a getSizeOfZoo() method for you, to get rid of the Id variable. Changed String for area to a Double. Keep your classes seperate, keep the naming convention Class, variable, methodName() etc. It makes it much easier to read. The parameters when creating a lion and tiger were a little off, I've put it as name, type, age, gender now.
Check out the javadoc for ArrayList and you can figure out how to 'remove' an element from your ArrayList (I'm reluctant to do your project FOR you). The issues you have encountered are more around coding basics rather than anything Java specific, or OOP specific. Have a read up, try the mothod removeAnimal(animal an) and see how you get on. We can help if there is any issue, but look at getSizeOfZoo() and addAnimal() and the docs and you should be flying!
Hope that helps.