How to reflect inheritance and polymorphism in the database? - java

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.

Related

How to cast an object of an ArrayList of objects (of type superclass) to an object of type subclass

If I have a superclass, let's call it Car, with the constructor parameters String name, String color, double wheelSize, and a subclass of this, let's call it Truck, with the constructor parameters String name, String color, double wheelSize, and double truckBedArea, and in the subclass (Truck), I have a method called modifyCar with the paramaters Car car, String newName, String newColor, double newWheelSize, and double newTruckBedArea, how can I find a way to take that Car object and specify that it is indeed a Truck, so I can then use a Truck setter (setTruckBedArea) to set the new truck bed area? This example isn't a great comparison to my actual assignment, but I have an ArrayList field of my superclass (Cars) called "ArrayList cars" of "Car" objects, and I need to find a way to change that "Car" object in this ArrayList field, which I have already found a way of doing. I simply loop through each item in the ArrayList of "Cars" until it equals the instance of the Car put in as a parameter, and if it does, I then say "cars.get(i).//setter" (essentially). However, it would not work if I say "cars.get(i).setTruckBedArea(newTruckBedArea)". I am not sure how to cast the Car object within this list of Cars to a Truck specifically, so I can then access the setter I want to use. The main issue is that I am required to implement an interface (let's call it "Vehicle") wherein the ArrayList cars has to be of type cars, since it is specified to be that in the Vehicle interface (otherwise I would just change the ArrayList field to be ArrayList trucks).
Example:
public class Truck implements Vehicle { //have to implement this interface
//... other fields
private ArrayList<Car> cars;
//... other methods/constructors
public void modifyCar(Car car, String newName, String newColor, double newWheelSize, double newTruckBedArea) {
//have to have "Car car" as parameter for this method because of interface
for (int i = 0; i < cars.size(); i++) {
if (cars.get(i).equals(car)) {
cars.get(i).setColor(newColor);
cars.get(i).setName(newName);
cars.get(i).setWheelSize(newWheelSize);
cars.get(i).setTruckBedArea(newTruckBedArea); //will produce error
}
}
}
}
As far as I understand the question, you can use "instanceof" operator:
if(cars.get(i) instanceof Truck){
Truck truck = (Truck) cars.get(i);
truck.setTruckBedArea(newTruckBedArea);
}
instanceof operator returns a boolean value in result of whether an object is an instance of given type or not.
Vehicle should be an Abstract class.
Car Interface
public interface Car {
void modifyCar(Car car, String newName, String newColor, double newWheelSize, double newTruckBedArea);
}
Vehicle Abstract Class
public abstract class Vehicle implements Car {
String name;
String color;
double wheelSize;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWheelSize() {
return wheelSize;
}
public void setWheelSize(double wheelSize) {
this.wheelSize = wheelSize;
}
}
Truck Class
public class Truck extends Vehicle {
double truckBedArea;
private ArrayList<Car> cars;
public double getTruckBedArea() {
return truckBedArea;
}
public void setTruckBedArea(double truckBedArea) {
this.truckBedArea = truckBedArea;
}
public ArrayList<Car> getCars() {
return cars;
}
public void setCars(ArrayList<Car> cars) {
this.cars = cars;
}
#Override
public void modifyCar(Car car, String newName, String newColor, double newWheelSize, double newTruckBedArea) {
for (int i = 0; i < cars.size(); i++) {
if (cars.get(i).equals(car)){
((Vehicle)cars.get(i)).setColor(newColor);
((Vehicle)cars.get(i)).setWheelSize(newWheelSize);
((Truck)cars.get(i)).setTruckBedArea(newTruckBedArea);
}
}
}
}
Run code.
public static void main(String[] args) {
// TODO code application logic here
Truck trucks = new Truck();
trucks.setColor("Red");
trucks.setName("Nissan");
trucks.setWheelSize(20.15);
trucks.setTruckBedArea(3.5);
ArrayList<Car> cars = new ArrayList<Car>();
cars.add(trucks);
trucks.setCars(cars);
trucks.modifyCar(trucks, "Kia", "Blue", 15.5, 14.0);
System.out.println(trucks.getTruckBedArea());
}

Creating Child Object, Child Constructor Not Used OOP

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");

Java Inheritance: Restrict List to Subclass Objects

Let's assume I have 3 classes: Car, Convertible and Garage.
Car:
public class Car {
private String name;
private String color;
public Car(String name, String color) {
this.name = name;
this.color = color;
}
//Getters
}
Convertible inherits from Car:
public class Convertible extends Car{
private boolean roof;
public Convertible(String name, String color, boolean roof) {
super(name, color);
this.roof = roof;
}
public boolean isRoof() {
return roof;
}
}
Garage stores a list of Cars:
public class Garage {
private int capacity;
private List<Car> cars = new LinkedList<Car>();
//Setter for capacity
}
How could I create a subclass of Garage called ConvertibleGarage that can only store Convertibles?
You could use a little bit of generics:
public class Garage<T extends Convertible> {
private int capacity;
private List<T> cars = new LinkedList<T>();
public Garage(int capacity) {
this.capacity = capacity;
}
}
This means when you instantiate a Garage you now have to include a parameter type that is a Convertible or child of it.
Garage<Convertible> cGarage = new Garage<>();
Generics will help here.
Make the Garage class generic Garage<T extends Car>, where a T is a car type it can store. Rewrite the cars list to a generic view List<T> as well.
Then, a Garage<Convertible> is going to be your "ConvertibleGarage".
You don't really need to make a second Garage class, you can use Generics :
public class Garage<T extends Car> {
private int capacity;
private List<T> cars;
public Garage() {
this.cars = new LinkedList<>();
}
public static void main(String[] args) {
Garage<Convertible> garConv = new Garage<>();
garConv.cars.add(new Convertible("", "", true));
Garage<Car> garCar = new Garage<>();
garCar.cars.add(new Car("", ""));
}
}
With this only class you can have a garage for car and a one for convertible
As the other answers have explained, you solve your problem by making your Garage class generic - and therefore allowing any instance of Garage to deal with exactly one kind of cars.
But what is missing so far: this is not "an option" to solve your problem - this is simply "the way to go here". Your idea of using inheritance is "plain wrong". Meaning: when people start with object oriented design, they assume that inheritance is the answer to everything. And actually that is not true. You are rather careful about creating an extends relation between two classes.
And especially when talking about containers - classes that "contain" other objects - then generics is your first thought!

How to extend or implement classes? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Picture to show task:
First I am sorry, for my bad to for expressing my mind.
I have such a task, I don't need that you do it for me.
Vehicle is parent class for Sedan (Cause Sedan class is String type).
How to extend or implement Vehicle class with universal class?
I forgot to ask my teacher, but maybe you will know, what means striped pointer to Owner class, and what is that: has a?
P.S. If you need code that I have written already, I will show you.
So this is my parent Vehicle class:
public class Vehicle {
private int vehicleNumber;
protected int fuelTankSize;
protected int maxSpeed;
protected Owner owner;
//1
public Vehicle(int vehicleNumber){
this.vehicleNumber = vehicleNumber;
}
//2
public Vehicle(int vehicleNumber, int fuelTankSize) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
}
//3
public Vehicle(int vehicleNumber, int fuelTankSize, int maxSpeed) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
this.maxSpeed = maxSpeed;
}
//4
public Vehicle(int vehicleNumber, int fuelTankSize, int maxSpeed, Owner owner) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
this.maxSpeed = maxSpeed;
this.owner = owner;
}
//1
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed (int maxSpeed){
this.maxSpeed = maxSpeed;
}
//2
protected int getFuelTankSize(){
return fuelTankSize;
}
protected void setFuelTankSize (int fuelTankSize){
this.fuelTankSize = fuelTankSize;
}
//3
public Owner getOwner(){
return owner;
}
public void setOwner (Owner owner){
this.owner = owner;
}
}
child Sedan with:
public class Sedan extends Vehicle {
private String registrationIndex;{
}
public Sedan (int vehicleNumber, int fuelTankSize, int maxSpeed, String registrationIndex, Owner owner) {
super(vehicleNumber, fuelTankSize, maxSpeed, owner);
this.setRegistrationIndex (registrationIndex);
}
public String getRegistrationIndex (){
return registrationIndex;
}
public void setRegistrationIndex (String registrationIndex) {
this.registrationIndex = registrationIndex;
}
}
second Universal child without an error:
public class Universal extends Vehicle {
private int trunkSize;
public Universal (int vehicleNumber, int fuelTankSize, int maxSpeed, int trunkSize, Owner owner) {
super(vehicleNumber, fuelTankSize, maxSpeed, owner);
this.setTrunkSize (trunkSize);
}
public int getTrunkSize() {
return trunkSize;
}
public void setTrunkSize(int trunkSize) {
this.trunkSize = trunkSize;
}
public void printDescription() {
super.printDescription();
System.out.println("Universalo bagažinės tūris: " + getTrunkSize() + "l.");
}
}
and some misterious (to me) Owner class:
public class Owner {
public String firstName;
public String lastName;
public Owner (String firstName){
this.firstName = firstName;
}
public Owner (String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
}
added VechileTest for testing:
public class VehicleTest {
public static void main(String[] args) {
Vehicle vehicleInf = new Vehicle (1, 45, 260);
Universal universalInf = new Universal(2, 50, 220, 70);
Sedan sedanInf = new Sedan (3, 40, 180, "AVA 123");
vehicleInf.printDescription();
universalInf.printDescription();
sedanInf.printDescription();
}
}
Well, 1st of all I recommend you read a good tutorial / explanation of UML class diagrams, like this here for example.
After you know the basics, it should be easy to translate that into Java code.
I'll give you the code for the Universal class and a start for your Vehicle. The rest you'll have to do on your own.
The class Universal:
public class Universal extends Vehicle {
private int trunkSize;
public int getTrunkSize() {
return this.trunkSize;
}
public void setTrunkSize(int trunkSize) {
this.trunkSize = trunkSize;
}
}
As you can see the first block inside a class box refers to the variables. The - and + indicates the visibility (private for -, public for +).
The next block is about the methods, specifying visibility, return type, method name and parameters (type and name).
The arrow between Universal and Vehicle indicates a inheritance relationship (see in code that Universal extends Vehicle).
So all in all the diagram is a construction plan for your classes; at least for the static part, meaning the relationships and state they can have.
The start of class Vehicle:
public class Vehicle {
private int vehicleNumber;
// the rest here ...
}
Edit:
Well, now that I see your code, you seem to have a few misconceptions:
The Sedan type is not from type String, it is from type Sedan (which extends Vehicle). Just the new member variable in the Sedan type is of type String, does not matter.
To your 1st question: The Vehicle class is the base (parent) class of Sedan. You do not to do anything with it, inheritance is expressed from the child towards the parent, not the other way around. Vehicle should usually be declared abstract (as you cannot create an instance of a generic Vehicle), but this is not in the diagram.
To your 2nd question: The has a relationship is just this. It expressed that one class has another class as it's member (which is redundantely expressed inside the class diagram already), so nothing to do for that.
Additionally your code has a few issues:
I do not see any constructors declared in Vehicle class, those 4 can go.
Your Sedan has a superflous pair of {} after declaration of your registrationIndex variable.
Since your Vehicle has no default constructor, you must call this constructor from your Sedan class (or remove the constructors from Vehicle.
Your Universal class calls the Vehicle constructor with the trunkSize while the Vehicle constructor expects the vehicleNumber there.
Your Vehicle class doesn't have a parameterless constructor, which means that Universal and Sedan must explicitly call one of them (super(...);). You're doing this in Universal (albeit incorrectly as you're passing the trunk size instead of the vehicle number expected by Vehicle's constructor) but not in Sedan.
As for the second question: The two major relations in OOP are is a and has a. The difference can be easily explained like this:
A Sedan is a vehicle
A vehicle has an owner
is a means it inherits some properties of something else, has a means that it has a reference to something else.

How to use array list ? [Oop]

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.

Categories