I am defining the characteristics of a Dog class which contains instance data defining their name and age, making constructors for this data, setter-getter methods, etc. I also have a method which returns the value of "dog years" (aka, seven years times a human year that passes for their equivalent age). I have a driver class, Kennel, which main method instantiates and updates these Dog objects, and prints them out.
In the Kennel class, one of my last statements you can see a comment that says ""INQUIRE AT SOME POINT".
I.e: //Dog dog3 = dog2.setName("Krypto");
In the comment, I have tried to make a new Dog object called "Kryto" while assigning the rest of the dog2 object's data to it via a setName method. In other words, I want my dog3 object to have all of dog2's characteristics with the exception of the name.
What would be the way to accomplish this? I understand that I can't use an object as a parameter, right?
Here's my code for the two classes below:
Kennel (Driver):
public class Kennel {
//instance data
int age;
public static void main(String[] args) {
//dog objects
Dog dog1 = new Dog("Bear", 3);
Dog dog2 = new Dog("Bella", 7);
//calling the method required to calculate the dog's human years, so that when I print these objects out, they actually have their traits
//(that being, their "dogman" age.
dog1.calcDogmanYears();
dog2.calcDogmanYears();
//output
System.out.println(dog1);
System.out.println(dog2);
dog2.setName("Krypto");
//Dog dog3 = dog2.setName("Krypto"); //INQUIRE AT SOME POINT
System.out.println(dog2);
}
}
Dog:
public class Dog {
//instance data
String name;
int age;
//constructor (normal) to allow objects to have values by default (i.e. no requirement of forcing parameters down the methods from the driver class)
public Dog() {
name = "";
age = 0;
return;
}
//constructor, keep in mind for future reference, that I used different variables to allow the constructor to be overloaded in a driver class to
//follow Chapter 4's constructor Java syntax. We could've overloaded the constructor with formal parameters of the same name as the instance data
//with the "this.(insert variable here)" modifier. I did this for shits and giggles.
public Dog(String name, int age){
this.name = name;
this.age = age;
return;
}
//method to convert dog to human years
public int calcDogmanYears() {
age = age * 7;
return age;
}
//setters and getters for name
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
//mutators and accessors for age}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public String toString() {
String result = "The name of the dog is " + name + ", and their age is " + age + " years old.";
return result;
}
}
One option would be to make the Dog class cloneable. Clone the original, then set the name appropriately.
Dog dog3 = dog2.clone();
dog3.setName("Krypto");
Kennel (Driver) class:
public class Kennel {
//instance data
int age;
public static void main(String[] args) throws CloneNotSupportedException {
//dog objects
Dog dog1 = new Dog("Bear", 3);
Dog dog2 = new Dog("Bella", 7);
//calling the method required to calculate the dog's human years, so that when I print these objects out, they actually have their traits
//(that being, their "dogman" age.
dog1.calcDogmanYears();
dog2.calcDogmanYears();
//output
System.out.println(dog1);
System.out.println(dog2);
dog2.setName("Krypto");
Dog dog3 = dog2.clone();
dog3.setName("Krypto"); //INQUIRE AT SOME POINT
System.out.println(dog2);
}
}
Updated Dog class:
public class Dog implements Cloneable {
//instance data
String name;
int age;
//constructor (normal) to allow objects to have values by default (i.e. no requirement of forcing parameters down the methods from the driver class)
public Dog() {
name = "";
age = 0;
}
// Overriding clone() method of Object class
public Dog clone() throws CloneNotSupportedException{
return (Dog) super.clone();
}
public Dog(String name, int age){
this.name = name;
this.age = age;
}
//method to convert dog to human years
public int calcDogmanYears() {
age = age * 7;
return age;
}
//setters and getters for name
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
//mutators and accessors for age}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public String toString() {
String result = "The name of the dog is " + name + ", and their age is " + age + " years old.";
return result;
}
}
output:
The name of the dog is Bear, and their age is 21 years old.
The name of the dog is Bella, and their age is 49 years old.
The name of the dog is Krypto, and their age is 49 years old.
You can define a new method in Dog class:
public Dog createTheSameAgeDog(String name) {
return new Dog(name, this.age);
}
Then call it:
Dog dog3 = dog2.createTheSameAgeDog("Krypto"); // creates the Dog (age 7, name "Krypto")
Related
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
What's the simplest way to print a Java array?
(37 answers)
Closed 26 days ago.
(Homework) Briefly, i have 3 classes; Dog, Owner, ListOfDogs. I also have class Register, which handels all the methods that the user of the program can execute.
One required function of the program is that the toString() method of the Owner-class also needs to be returning the name of the owners dogs, which are instances of the class Dog, stored in an Array that is in ListOfDogs.
The Array that stores the dogs are private. I'm not by any means allowed to give access to the Array. So no getters or anything like that. The relationship between these classes needs to look like this:
relationship between classes
Instead of the dogs name being printed after the owners name, i get this when trying :
Name: Kasper ListOfDogs#7ea987ac
Name: Augusta ListOfDogs#12a3a380
Name: Liselott ListOfDogs#29453f44
Name: Lisa ListOfDogs#5cad8086
Name: Agneta ListOfDogs#6e0be858
Why does this happen, and is there anyway i could make the Owner toString() return the owners dogs name without giving access to the Array in ListOfDogs?
I will post all the code i believe is relevant:
public class Owner {
private String name;
private ListOfDogs dogList;
public Owner (String name){
this.name = name;
this.dogList = new ListOfDogs();
}
#Override
public String toString(){
return "Name: " + name + " " + dogList.toString();
}
public String getName(){
return name;
}
public boolean ownsDog (Dog dog){
return dogList.searchDog(dog);
}
}
public class ListOfDogs {
private Dog[] userDogs;
public ListOfDogs(){
this.userDogs = new Dog[0];
}
public String toString(){
return Arrays.toString(userDogs);
}
public boolean searchDog (Dog dog){
for (Dog d : userDogs) {
if (d.getName().equalsIgnoreCase(dog.getName())) {
return true;
}
}
return false;
}
}
public class Dog {
public Dog(String name, String breed, int age, int weight) {
this.name = name;
this.breed = breed;
this.age = age;
this.weight = weight;
}
public String getName() {
return name;
}
public Owner getOwner() {
return owner;
}
}
public class Register {
private ArrayList<Dog> dogs = new ArrayList<>();
private ArrayList<Owner> owners = new ArrayList<>();
public void listOwners() {
if (owners.isEmpty())
System.out.println("Error: no owners in register");
for (Owner o : owners) {
System.out.println(o);
//this below is a temporary solution that i don't think will pass the assignment
for (Dog d : dogs) {
if (d.getOwner() == o)
System.out.println(d);
}
}
}
}
How can I access to members of each classes?
I have class Dog and Cat. They have different member variable of class.
I try to create one function "CommUtil.display()" to access many classes (Dog or Cat) and display all members of class.
I try to access from mainClass to access Dog or Cat class.
but it can't.
Anyone can help will be appreciated.
I have made an example below:
class Dog {
private String name = null;
private String weight = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
}
class Cat {
private String name = null;
private String age = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class commUtil {
//TODO: output members of class
public void display (Object obj){
//Question: How to access members of each classes?
//code here...
}
}
class mainClass {
public static void main(String[] args) {
Dog d = new Dog();
commUtil.display(d);
or
Cat c = new Cat();
commUtil.display(c);
}
}
In case 1:
Dog d = new Dog();
d.setName("Lion");
d.setWeight("2Kg");
commUtil.display(d);
It will display Name and Weight of Dog
In case 2:
Cat c = new Cat();
c.setName("MiMi");
c.setAge("1");
commUtil.display(c);
It will display Name and Age of Cat
If the code can still change, you may be able to use java interface. The idea is that both Dog and Cat implements a common interface for output display. In practice though, it will have the same result as modifying toString() like the other comments already covered. Anyway, here is an example:
public interface AnimalInfo {
public String getInfo();
}
and then both Dog and Cat classes can implements this interface.
class Dog implements AnimalInfo {
...
public String getInfo() {
return "name="+name+", weight="+weight;
}
class Cat implements AnimalInfo {
...
public String getInfo() {
return "name="+name+", age="+age;
}
and then inside commUtil the argument can use the interface type AnimalInfo
public void display (AnimalInfo animal){
System.out.println("It will display " +
animal.getInfo() + " of " + animal.getClass().getSimpleName());
}
This is what inheritance is for, so you would make an abstract super class possibly called Animal in this case and then Dog and Cat would extend that class as subclasses. Here is a fairly simple tutorial about inheritance.
public abstract class Animal {
/** Common name property for all animals */
private String name;
/** Common age property for all animals */
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age= age;
}
public int getAge() {
return age;
}
/**
* Abstract method that will need to be implemented
* by a concrete class that inherits from this abstract class
*/
public abstract String getInfo();
public abstract String speak();
public abstract String getType();
}
public class Dog extends Animal {
/*
Any Dog specific properties would also go in here
*/
private boolean isPedigree = false;
/** Class Constructor */
public Dog(String name, int age, boolean isPedigree) {
super(name, age);
this.isPedigree = isPedigree;
}
public boolean isPedigree() {
return isPedigree;
}
#Override
public String getInfo() {
return "I am a Dog named " + name + " and I am " + age + " years old.";
}
#Override
public String speak() {
return "WOOF";
}
#Override
public String getType() {
return Dog.class.getSimpleName();
}
}
public class Cat extends Animal() {
/*
Any Cat specific properties would also go in here
*/
/** Class Constructor */
public Cat(String name, int age) {
super(name, age);
}
#Override
public String getInfo() {
return "I am a " + getType() + named " + name + " and I am " + age + " years old.";
}
#Override
public String speak() {
return "meow";
}
#Override
public String getType() {
return Cat.class.getSimpleName();
}
}
public class MyMainClass {
public static void main(String[] args) {
/*
Just creating a random array to show that
any animal whether Dog or Cat can be placed into
this array as they inherit from Animal
*/
List<Animal> animals = new ArrayList<>();
animals.add(new Dog("James", 5, true));
animals.add(new Cat("Treacle", 2));
for (Animal animal : animals) {
display(animal);
if (animal instanceof Dog) {
boolean isPedigree = ((Dog) animal).isPedigree();
System.out.println("Q: Am I a Pedigree? A: " + String.valueOf(isPedigree));
}
}
}
private void display(Animal animal) {
System.out.println("I'm an animal of type " + animal.getType() + " and I can say " + animal.speak());
System.out.println(animal.getInfo());
}
}
Our output would be:
I'm an animal of type Dog and I can say WOOF
I am a Dog named James and I am 5 years old.
Q: Am I a Pedigree? A: true
I'm an animal of type Cat and I can say meow
I am a Cat named Treacle and I am 2 years old.
This answer shows simple inheritance and polymorphism. This of the backbone of OOP (Object Orientated Programming) and when learning Java will be the essential basics you will need to learn and understand.
In my example getInfo() could actually just be a method in Animal as there is nothing specific it is doing per subclass. You could also move display into the Animal abstract class if you which, I only placed it here for the example.
There is no need for any CommonUtils class or anything like that here, everything you want can be done by simply learning about inheritance.
What we are saying in this example is Cat and Dog are Animals they inherit all the characteristics of any Animal. What you can't do though is create a random Animal object like Animal animal = new Animal("Paul", 4);, the Animal has to be of some sort of type whether that is of type Dog, Cat or some other Subclass of Animal you create (i.e. Bird, Fish or even Human).
You can have the CommonUtil class as shown below. Also, make the display method static as you are trying to access it using class name.
class CommUtil {
//TODO: output members of class
public static void display (Object obj){
//Question: How to access members of each classes?
//code here...
if(obj instanceof Dog) {
System.out.println(((Dog) obj).getName());
System.out.println(((Dog) obj).getWeight());
}
}
}
But as mentioned in the comments you can just override toString() method inside every class and display objects for all those classes.
public String toString() {
return "Cat [name=" + name + ", age=" + age + "]";
}
You can use Java reflection to get all fields from object, below is the example, you can achieve this by T parameter method in utility class
public class ArrayMain {
int x=10; String name="anil";
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
ArrayMain m = new ArrayMain();
m1(m);
SomeOther o = new SomeOther();
m1(o);
}
public int getX() {
return x;
}
public String getName() {
return name;
}
static <T> void m1(T type) throws IllegalArgumentException, IllegalAccessException {
Field[] f=type.getClass().getDeclaredFields();
for(Field f1:f) {
System.out.println(f1.getName());
System.out.println(f1.get(type));
}
}
}
Check if the object is an instance of Cat or Dog using the instanceof operator. Then you must perform a cast to access the object’s getter methods.
if(obj instanceof Cat){
Cat cat = ((Cat) obj);
System.out.println(cat.getName());
}
I've created one abstract class named Creature and two classes that extend Creature named Human and Dog. There are also some methods like getAge and setAge, as you can see:
public abstract class Creature {
public abstract void born(String name);
public abstract void setName(String name);
public abstract void setAge(int age);
public abstract int getAge();
public abstract String getName();
}
public class Human extends Creature {
private String name;
private int age;
public void born(String name){
setName(name);
setAge(0);
}
// getters and setters
}
public class Dog extends Creature {
private String name;
private int age;
public void born(String name){
setName(name);
setAge(0);
}
// getters and setters
}
And then I make this:
private static Creature creature;
String string = new Random().nextInt(2) == 1 ? "Human" : "Dog";
if (string.equals("Human")) {
setCreature(new Human());
} else {
setCreature(new Dog());
}
for (int i = 0; i < 5; i++) {
creature.born("Name" + i);
// here are born 5 creatures
}
// after one year get all creatures and set their age +1
My question is, how can I get all creatures born and after one year set their age with +1?
I assume that setCreature add a new creature inside a kind of list
you only have to do is to iterate over the list and increment the age without paying any attention to the type of creature
for(Creature c : creatures){
c.setAge(c.getAge() +1 );
}
I'm doing an assignment based around inheritance and I have created 2 constructors that are suppose to do different things. One constructor does not have any parameters and should produce a pre-defined value, the other constructor has 2 parameters which consist of a name and an age of types String and int. I have somehow reconfigured the two constructors so that they both do not produce what they should be. Here is the classes that these constructors are invoked in:
Animal (super class)
abstract public class Animal implements Comparable<Animal>
{
int age;
String name;
Animal(String name, int age)
{
this.age = age;
this.name = name;
}
Animal()
{
this("newborn", 0);
}
public int getAge()
{
return age;
}
public void setName(String newName)
{
name = newName;
}
String getName()
{
return name;
}
}
Carnivore
public class Carnivore extends Animal
{
Carnivore(String name, int age)
{
this.age = age;
this.name = name;
}
Carnivore()
{
super();
}
#Override
public int compareTo(Animal o)
{
//To change body of generated methods, choose Tools | Templates.
throw new UnsupportedOperationException("Not supported yet.");
}
}
Wolf
public class Wolf extends Carnivore
{
String name;
int age;
Wolf(String name, int age)
{
this.name = name;
this.age = age;
}
Wolf()
{
super();
}
String getName()
{
return name;
}
}
Main method
System.out.println("************1st constructor of Wolf************");
Wolf wolfExample = new Wolf("Bob", 2) {};
System.out.println("Name = " + wolfExample.getName());
System.out.println("Age = " + wolfExample.getAge());
System.out.println("************2nd constructor of Wolf************");
Wolf newWolf = new Wolf();
System.out.println("Name = " + newWolf.getName());
System.out.println("Age = " + newWolf.getAge());
Actual Output
************1st constructor of Wolf************
Name = Bob
Age = 0
************2nd constructor of Wolf************
Name = null
Age = 0
Expected Output
************1st constructor of Wolf************
Name = Bob
Age = 2
************2nd constructor of Wolf************
Name = newborn
Age = 0
The ages are returning their default value and the name for the second constructor is also returning null but I'm not too sure why. This is my first time working with multiple constructors so I'm a little confused as to ow it works so any help would be much appreciated, thanks.
Your base class seems correct, but you need to change your implementations.
Your Wolf and Carnivore constructors should be:
Wolf(String name, int age)
{
super(name, age);
}
Reason being, you are setting the local instance variables for each type, but calling getAge() method of the super class - this is getting the super's value of age, whose's value has not actually been assigned anywhere, and is given a default value of 0. This goes the same for name, which defaults to null.
You need to call super with the passed variables, and do not need to redefine them for each extended object.
class Human{
// declared instance variables
String name;
int age;
// instance method
void speak(){
System.out.println("My name is: " + name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return age;
}
String getName(){
return name;
}
// so when I create an instance, i can't have constructor?
// error here
Human(int age){
age = this.age;
}
}
}
public class GettersAndReturnValue {
public static void main(String[] args) {
// error here because I created a constructor Human(int a)
Human human1 = new Human();
human1.name = "Joe";
human1.age = 25;
human1.speak();
int years = human1.calculateYearsToRetirement();
System.out.println("Years till retirements " + years);
int age = human1.getAge();
System.out.println(age);
}
}
I tried to create a constructor Human(int age) to practice 'this' keyword and to change the age from 25 to something else but I get an error because I have one Human class and one Human constructor. When I try to create an instance of Human Type in my main method, eclipse is asking me to remove the constructor
You've swapped the order in your assignment,
Human(int age){
age = this.age;
}
should be something like (don't forget to initialize name too)
Human(int age){
this.age = age;
this.name = "Unknown";
}
You're assigning the default value 0 to the passed in parameter. If you provide a constructor then the compiler will no longer insert the default constructor,
Human() {
this.age = 0;
this.name = "Unknown";
}
and you might as well add a constructor that takes the name,
Human(int age, String name) {
this.age = age;
this.name = name;
}
then you could call it (in main) like
Human human1 = new Human(25, "Joe");
// human1.name = "Joe";
// human1.age = 25;
You have to create a no parameter constructor, because when you are calling Human h = new Human();, you are calling a no parameter constructor.
Try doing this instead:
Human h = new Human(age);
When you create a non-empty constructor, the empty constructor will not be available anymore. You do can have more than one constructor, but if you want the no-argument constructor along with other, you will have to recreate it.
//Please, make it public for constructors
public Human(int age){
this.age = age; //this.age first, to receive the parameter age
}
public Human() {} //Empty constructor. It doesn't has to be a content.
So you call:
Human humanOne = new Human(); //Using no-argument constructor
Human humanTwo = new Human(25); //Using constructor with int to set age
When you create a constructor in the class, it will no longer use the default constructor. In your code, you've created a public Human(int) constructor, so there is no default constructor. Because of that, you cannot create human object like this:
Human a = new Human();
To do that, you have to manually implement a no-argument Human constructor.
Here is a solution:
class Human{
String name;
int age;
//default constructor
public Human (){
}
//paramete constructor
public Human(int a){
this.age=a;
}
void speak(){
System.out.println("My name is: " + this.name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return this.age;
}
String getName(){
return this.name;
}
}
Here's the working code :
Create a class GettersAndReturnValue and add this. You need a empty constructor.
class Human{
// declared instance variables
String name;
int age;
// instance method
void speak(){
System.out.println("My name is: " + name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return age;
}
String getName(){
return name;
}
// so when I create an instance, i can't have constructor?
// error here
Human(int age){
this.age = age;
}
public Human() {
// TODO Auto-generated constructor stub
}
}
public class GettersAndReturnValue {
public static void main(String[] args) {
// error here because I created a constructor Human(int a)
Human human1 = new Human();
human1.name = "Joe";
human1.age = 25;
human1.speak();
int years = human1.calculateYearsToRetirement();
System.out.println("Years till retirements " + years);
int age = human1.getAge();
System.out.println(age);
}
}
Output :
My name is: Joe
Years till retirements 40
25