UML Diagram
I am brand new to Java, though I've taken other programming courses. I'm really struggling with the class concept from a UML diagram. I have a parent class and two child classes. My assignment is to create this class structure. I am struggling with the concept of class and relationships in general though.
Example: If my parent class is "Animal" and my child classes are "Monkey" and "Bear" - if the only choices that will be implemented are "Monkey" and "Bear", this makes the class "Animal" an abstract class distinction as there will never be just "Animal", it will always be a "Monkey" or a "Bear".
So, how would I create three files (Animal.java, Monkey.java, Bear.java) if Animal is abstract? I understand that the properties and traits of Animal are inherited by Monkey and Bear. Assuming that I have, for instance, name and age of the animal as attributes and getters and setters for each - if name and age of "Animal" class are private (code below), how does "Bear" class pick up the name and age if it is in its own java file/class? My code is below...
Animal.java
public class Animal {
private String animalName;
private int animalAge;
public void setName (String name) {
animalName = name;
}
public void setAge (int age) {
animalAge = age;
}
public static String getName() {
return animalName;
}
public static String getAge() {
return animalAge;
}
}
Bear.java
public class Bear {
public int weight;
public static int weight() {
return weight;
}
}
// This is where I get stuck & don't know where to go from here.
I understand that I am creating an object "Bear" which is part of the class "Animal", but as Bear is its own class, how does "Bear" get its assigned values from Animal? I can assign "Animal" and "Bear" with default values, but my brain cannot put together how they're talking to one another.
This might be outside the scope of this forum but my professor is unresponsive and I've read through books, ebooks, the course material, and several lectures and this is just not coming to me and I'm two weeks behind at this point trying to understand this concept so I can move forward with the actual code in the program.
Thanks in advance.
You forgot to do this:
public class Bear extends Animal {
// ...
}
I would recommend that you add constructors:
public class Animal {
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() [ return this.name; }
public int getAge() { return this.age; }
}
public class Bear extends Animal {
private int weight;
public Bear(String name, int age, int weight) {
super(name, age);
this.weight = weight;
}
public int getWeight() { return this.weight; }
}
You can do this, because Bear IS-A Animal:
Animal b = new Bear("Smokey", 10, 300);
System.out.println(b.getName()); // prints "Smokey"
Related
I am new to java and I am trying to work a simple program. I have created a class and defined the variables like this
public class Animal {
private String age;
private String color;
Breed breed;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Breed getBreed() {
return breed;
}
public void setBreed(Breed breed) {
this.breed = breed;
}
}
class Breed {
private String afador;
private String afaird;
private String aussiepom;
public String getAfador() {
return afador;
}
public void setAfador(String afador) {
this.afador = afador;
}
public String getAfaird() {
return afaird;
}
public void setAfaird(String afaird) {
this.afaird = afaird;
}
public String getAussiepom() {
return aussiepom;
}
public void setAussiepom(String aussiepom) {
this.aussiepom = aussiepom;
}
}
I want to access the variables in class "BREED" from ANOTHER file, with "animal.breed..." which does not work. How can I access the variables in the "BREED" class?? I am not sure if it is because I have the getter and setters in this file, kindly advise on the same.
I think I see what you are trying to do, however, you did not provide any sample code so I will be answering based on assumptions.
To start, you are trying to access a variable from inside of the Breed class through the getter methods. Lets look at some code.
// I'm assuming this is similar to what you have set up.
// Make a new breed
Breed breed = new Breed();
// Setting the breed to Afador through your methods
breed.setAfador("Afador");
// Make a new animal
Animal animal = new Animal();
// Set our animal's breed to our newly made breed
animal.setBreed(breed);
You mentioned you got the getBreed() method to work, so you must have done something along the lines of
animal.getBreed();
You then mentioned you could not get getAfaird() method to work, so I assume you did something like this
animal.getAfaird();
This does not work since getAfaird() does not exist within the Animal class but rather the Breed class. You can only use this getAfaird() method on Breed objects. So you would want to do something like this
animal.getBreed().getAfaird();
You must be user the get method:
Animal animal = new Animal();
Breed breed = animal.getBreed();
Another option is declare public the breed attribute, but not is a good practique
Just a question RE: Constructor Chaining in subclasses that I can't find a good answer on and I'm confusing myself a bit with.
I'm making a basic little Text Based RPG for some practice and I'm going through my constructors for an abstract class and have the constructors from 0-4 params chained together like below
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
// Constructors + Chaining
public Creature() {
this("Unknown")
}
public Creature(String name) {
this(name, 100);
}
public Creature(String name, int lifeForce) {
this(name, lifeForce, 10);
}
public Creature(String name, int lifeForce, int strength) {
this(name, lifeForce, strength, 10);
}
public Creature(String name, int lifeForce, int strength, int agility) {
this.name = name;
this.lifeForce = lifeForce;
this.strength = strength;
this.agility = agility;
}
My confusion is how best to format the constructors of a subclass of creature, for example this simple Person class introduces two new fields. There's definitely too much repetition if I write the constructors like this
// Constructors + Chaining
public Person() {
super("Unknown");
this.skillClass=new Mage();
this.dialogue="...";
}
public Person(String name) {
super(name);
this.skillClass=new Mage();
this.dialogue="...";
} etc etc etc
I suppose I could restrict the constructors to limit the repetition but I'm mostly just wondering if there's good best practice that I'm missing here.
Any and all suggestions welcome and if anyone has any good resources to recommend that go deeper than the usual
Class B extends Class A
examples I'd massively appreciate.
In situations like this one when you need to use multiple constructors with different parameters, it is recommended to use the builder pattern like this :
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
private Creature(Builder<?> builder) {
this.name = builder.name;
this.lifeForce = builder.lifeForce;
// Add the other attributes here.
}
public static abstract Builder extends Builder<T extends Builder<T>> {
private String name;
private int lifeForce;
private int strength;
private int agility;
public Builder(//here you put the attributes that you need to have in all instances) {
// here you do the affectations.
}
// now you need to make the functions that set each property :
public Builder lifeForce(int lifeForce) {
this.lifeForce = lifeForce;
return this;
}
// you do the same thing for all the other attributes.
...
public Creature build() {
return new Creature(this);
}
}
}
So for the explanation : This pattern will allow you to create instances of your class by setting only the needed attributes.
As here you have subclasses the builder pattern will be little bit more harder to understand but it is the perfect solution in such situation.
We need to apply the builder pattern also for every subclasse so let's do it for the person class :
public class Person extends Creature {
private int anotherField;
public Person(Builder builder) {
super(builder);
this.anotherField = anotherField;
}
public static Builder extends Creature.Builder<Builder> {
public Builder(//add the fieldHere if it is needed in all class instances) {
// if the field is not mandatory you can omit this constructor but you need to put the function below.
}
public Builder anotherField(int anotherField) {
this.anotherField = anotherField;
}
public Person build() {
return new Person(this);
}
}
Now let me show you how tricky is this solution :
1/ declare person with 2 fields :
Person p1 = Person.Builder().name("name").anotherField(0).build();
2/ declare another one with just one field
Person p2 = Person.Builder().agility(1000).build();
Remark : In these two examples, i supposed that your builders' constructors don't have parameters. If for example the name is mandatory field :
Person p3 = Person.Builder("name").anotherField(0).build();
I wish that you had the idea about using builder pattern.
I have the following interface:
public interface IStaff {
public StaffPosition getPosition();
public String toString();
}
and the class:
public class Worker implements IStaff {
private String name = null;
private String surname = null;
private int age = 0;
//StaffPosition is an enumeration class
private StaffPosition position= null;
public Worker (String name, String surname, int age, StaffPosition position){
this.name = name;
this.surname= surname;
this.age= age;
this.position= position;
}
#Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(this.name);
buffer.append(" ");
buffer.append(this.surname);
return buffer.toString();
}
#Override
public StaffPosition getPosition() {
return this.position;
}
public int getAge(){
return this.age;
}
In another class - Building, I have a HashMap<Office, IStaff> officeswhere Office is a normal class which only holds the number of the office and has a getter for that number.
And then in a yet another class Company I have an ArrayList<Building> buildings, which holds information about all the buildings of a company. In this class I need to get the age of a worker but how can I do that? So far I have a loop like this to get to the map:
for (Building building: buildings) {
for (Map.Entry<Office, IStaff> office: building.offices.entrySet()) {
//get the age of a worker
}
}
Is there a way to do that?
The only real answer is: when you need such an information in places where only your interface should show up, then that information needs to sit on the interface.
So your interface could have a method getAge(), or maybe getBirthday().
Side notes:
using I for "interface" in class names ... is bad practice, or at least: very much against java conventions.
you don't need to have a toString() in your interface. You get one from Object anyway.
(of course, there are dirty tricks, like doing an instanceof check somewhere, and then casting to the type of the concrete class. But as said: that is really bad practice)
Make IStaff an abstract class and then call the method.
Consider this scenario,
I have two classes Student and HonorsStudent respectively.
class Student{
String name;
int roll;
Student(String name, int roll){
this.name = name;
this.roll = roll;
}
}
class HonorStudent extends Student{
int honorid;
HonorStudent(String name, int roll,int honorid){
this.name = name;
this.roll = roll;
this.honorid = honorid;
}
HonorStudent(String name, int roll){
this.name = name;
this.roll = roll;
}
}
Now, there might be scenarios in which I might want to convert a Student into an HonorStudent. Since downcasting is not allowed in this situation, I can't do this:
Student s1 = new Student("abc",123);
HonorStudent s = (HonorStudent)s1;
So the other way of doing this would be to define a method in HonorStudent which inputs a Student Object and returns a HonorStudent:
public static HonorStudent convertToHonor(Student s){
return new HonorStudent(s.name,s.roll);
}
This is convenient if there are only two attributes(name, roll), but what if I have a lot of attributes say 50 ? In that case I would have to input each and every attribute into HonorStudent?
I strongly feel there might be an easier way to do this?
You are asking if there is a more convenient way to do this. If we consider just copying parameters from one object to another then there is no another way to do this. There might be ways to work around the problem by having objects for groups of member fields or by automating it by code that can copy member fields with same name from object to another.
Small fix
But first, let's improve design a bit. Fields should not be duplicated like this between classes in a class hierarchy. So let's eliminate that duplication:
public class Student {
private String name;
private int roll;
public Student(String name, int roll) {
this.name = name;
this.roll = roll;
}
public String getName() {
return name;
}
public int getRoll() {
return roll;
}
}
public class HonorStudent extends Student {
private int honorId;
public HonorStudent(String name, int roll, int honorId) {
super(name, roll);
this.honorId = honorId;
}
public int getHonorId() {
return honorId;
}
}
Copy constructor
If there is really a need to copy objects then copy constructor can be useful. Creating a copy constructor will allow you to skip passing each member field only by one.
public Student(Student other) {
this.name = other.name;
this.roll = other.roll;
}
Then creating Student part of the HonorStudent becomes simpler
public HonorStudent(Student student, int honorId) {
super(student);
this.honorId = honorId;
}
Design
Now it is not common that objects change their type. So this is not a common thing to do. This is usually solved by different kind of design of classes. For example, honorId could be part of Student class because, I guess, student can gain this attribute or loose it. Behaviour related to honor can be in some other class that is attached to student class.
Reading about behavioural design patterns can be useful. Depending which pattern to choose will depend on the use case and the problem that you are trying to solve.
The Question is:
1) How can i get subclass parameter values to superclass?
2) i want to take the name(From subclass) for collection.sort , like this.model.compareTo(other.model). However, I don't know how to get the "Name" Value from subclass and do the collection.sort.
** Is it correct to write public int compareTo(Car other, Taxi other2)??? **
Here is the code:
public class Car implement comparable <Car>()
{
private string model;
private int price;
public car(String model , int price)
{
this.model=model;
this.price=price;
}
............some getmethod here..........
public int compareTo (Car other)
{
** Want to sort by name , like this.model.compareTo(other.model)**
}
}
Taxi.java:
public class taxi extends Car ()
{
private string name;
public taxi (String model , int price, String name)
{
super(model, price);
this.name = name;
}
......some getmethod here..........
}
you can use subclass values by creating object of sub class in superclass.
It is also known as delegation.