Beginner Java OOP - java

I am developing a simple Dog class to create dog objects and display the results.
Dog
_________
int - size
String - breed;
String - name;
__________
Dog(int, String, String)
bark()
bark(int)
toString(): String
print()
I have made the class successfully using getters and setters but my problem is the toString and print methods. I understand the toString method should return a string with the dog details but don't know how to print them.
I could in theory print it like this:
Dog a = new Dog ();
String details = a.toString();
System.out.println(details);
But this isn't how it's specified in the UML spec.
Should the toString method call the print method itself?
and if so, how?
Dog class:
class Dog{
private int size;
private String breed;
private String name;
//Create getter and setter methods:
public void setName (String name){
this.name = name;
}
public void setSize (int size){
this.size = size;
}
public void setBreed (String breed){
this.breed = breed;
}
public int getSize () {
return this.size;
}
public String getBreed () {
return this.breed;
}
public String getName () {
return this.name;
}
public void bark () {
System.out.println("Ruff! Ruff!");
}
public void bark (int amtOfBarks){
for (int i = 0; i < amtOfBarks; i++){
System.out.print("Ruff! Ruff! ");
}
}
public String toString () {
return "Name: "+this.name+"\nBreed: "+this.breed+"\nSize: "+this.size;
}
}
Main Method:
class TestDog {
public static void main (String [] args){
Dog rex = new Dog();
rex.setName("Rex");
rex.setBreed("poodle");
rex.setSize(1);
rex.toString();
rex.bark(3);
}
}

From your Class structure diagram, the print() method should call System.out.println(this);.
Note : The toString() will be called implicitly. in System.out.println

Agree with klemenp.
write your toString() method as follows:
#override
public String toString () {
return "Name: "+this.name+"\nBreed: "+this.breed+"\nSize: "+this.size;
}
and it will be implicitly called when you print the Object:
Edit to your code :
class TestDog {
public static void main (String [] args){
Dog rex = new Dog();
rex.setName("Rex");
rex.setBreed("poodle");
rex.setSize(1);
//rex.toString();
System.out.println(rex);
rex.bark(3);
}
}

The toString() method should not call the print() method. It should be the other way around.
Override toString() and call it from the print() method.
#Override
public String toString()
{
return "details";
}
public void print()
{
System.out.println(this.toString()); // same as System.out.println(this);
}

in class Dog
public String toString(){
return "details of dog";
}
so you can:
a = new Dog();
....
System.out.println(a);

from the doc of toString
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.
so to show your own details you have to override this method. a casual example is given here
public String toString(){
String s = /// add your detials
return s;
}
now from the code where you are using dog instance print dog.toString()

Creating a dog in this case is :
Dog a = new Dog (120, "breedname", "name");
In order to print the details you need getters,
in a create a get function like
getBreed(){
return breed; }
in dog, then to print you use:
System.out.println(a.getBreed());

in Class Dog write toString() as follows :
#Override
public String toString() {
return "String describing the details about Dog class";
}
Here #Override annotation is required, because every class has Default toString() method inherited from Object class....

To represent your object as String you have to override toString() method.
It is usually done as below (Eclipse as an example can generate it for you, using fields you will tell)
class Dog {
private int size;
private String breed;
private String name;
//constructors, methods, getters and setters
#Override
public String toString() {
return "Dog [size=" + size + ", breed=" + breed + ", name=" + name
+ "]";
}
}
Then you may use your instance object directly in System.out.println() and you will get String representation. You do NOT need to do as you said String details = a.toString(); and only then use it.
Dog dogInstance = new Dog(21, "Dog Breed", "Dog Name");
System.out.println(dogInstance);
As a result will be:
Dog [size=21, breed=Dog Breed, name=Dog Name]

Related

How to use function parameter: call specific getter

I have a Dog class with a name and a breed. I want to print either the dog's name or its breed depending on a method parameter passed to a printDog method. How do I do that?
class Dog {
private String name;
private String breed;
//constructor
public String getName() {
return name;
}
public String getBreed() {
return breed;
}
}
public void printDog(Dog dog, ?) {
System.out.println(dog.?);
}
Dog dog = new Dog("Buster", "Shepherd");
printDog(dog, dog::getName);
printDog(dog, dog::getBreed);
Use a Function<Dog, String>. This represents a function that takes a Dog and returns a String.
public void printDog(Dog dog, Function<Dog, String> propertySelector) {
System.out.println(propertySelector.apply(dog));
}
You can call this exactly the way you wanted:
Dog dog = new Dog("Buster", "Shepherd");
printDog(dog, dog::getName);
printDog(dog, dog::getBreed);

How to access parent class variable in child class inside a child method?

I have a class
public class A {
private String name;
public void setName(String name){
this.name = name;
}
public string getName(){return name;}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(name).append(", ");
return builder.toString();
}
}
I have a child class B that extends A and I have to access name from A in toString method in B. I have written the following code but not sure if this a good practice?
public class B extends A {
private String gender;
public void setGender(String gender){
this.gender = gender;
}
public string getGender(){return gender;}
#Override
public String toString() {
c = new A();
StringBuilder builder = new StringBuilder();
builder.append(c.getName()).append(", ");
builder.append(gender).append(", ");
return builder.toString();
}
}
EDIT:
If I cannot access private String name in class B, do I have to #Override setName() by using super.setName(name)? In that case how different it is from using class B without extending class A if I dont want to use any of the objects of A?
I just started using JAVA to modify a service.
When you inherit a class, you also inherit all the public and protected methods and variables from the inherited. So you can just do
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(this.getName()).append(", ");
builder.append(this.getGender()).append(", ");
return builder.toString();
}
simply by calling getName() in your toString method or super.getName()
like:
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(getName()).append(", ");
builder.append(gender).append(", ");
return builder.toString();
}
Never forget the old adage: You don't inherit your parent's privates.
If you want B to have access to A.name, you have a couple of options:
Change name to be either public (bad) or protected (better) in A.
Access name through A's setters and getters, e.g. this.getName()
Use reflection
What you've currently done just returns the default value of A.name and not the value of name that actually belongs to your instance of B.

Trying to figure out Inheritance and polymorphism

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}

Use of "this" keyword in java [duplicate]

This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
Closed 7 years ago.
I was studying method overriding in Java when ai came across the this keyword. After searching much about this on the Internet and other sources, I concluded that thethis keyword is used when the name of an instance variables is same to the constructor function
parameters. Am I right or wrong?
this is an alias or a name for the current instance inside the instance. It is useful for disambiguating instance variables from locals (including parameters), but it can be used by itself to simply refer to member variables and methods, invoke other constructor overloads, or simply to refer to the instance. Some examples of applicable uses (not exhaustive):
class Foo
{
private int bar;
public Foo() {
this(42); // invoke parameterized constructor
}
public Foo(int bar) {
this.bar = bar; // disambiguate
}
public void frob() {
this.baz(); // used "just because"
}
private void baz() {
System.out.println("whatever");
}
}
this keyword can be used for (It cannot be used with static methods):
To get reference of an object through which that method is called within it(instance method).
To avoid field shadowed by a method or constructor parameter.
To invoke constructor of same class.
In case of method overridden, this is used to invoke method of current class.
To make reference to an inner class. e.g ClassName.this
To create an object of inner class e.g enclosingObjectReference.new EnclosedClass
You are right, but this is only a usage scenario, not a definition. The this keyword refers to the "current object". It is mostly used so that an object can pass itself as a parameter to a method of another object.
So, for example, if there is an object called Person, and an object called PersonSaver, and you invoke Person.SaveYourself(), then Person might just do the following: PersonSaver.Save( this );
Now, it just so happens that this can also be used to disambiguate between instance data and parameters to the constructor or to methods, if they happen to be identical.
this keyword have following uses
1.used to refer current class instance variable
class Student{
int id;
String name;
student(int id,String name){
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student s1 = new Student(111,"Karan");
Student s2 = new Student(222,"Aryan");
s1.display();
s2.display();
}
}
here parameter and instance variable are same that is why we are using this
2.used to invoke current class constructor
class Student{
int id;
String name;
Student (){System.out.println("default constructor is invoked");}
Student(int id,String name){
this ();//it is used to invoked current class constructor.
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student e1 = new Student(111,"karan");
Student e2 = new Student(222,"Aryan");
e1.display();
e2.display();
}
}
3.this keyword can be used to invoke current class method (implicitly)
4.this can be passed argument in the method call
5.this can be passed argument in the constructor call
6.this can also be used to return the current class instance
This refers current object. If you have class with variables int A and a method xyz part of the class has int A, just to differentiate which 'A' you are referring, you will use this.A. This is one example case only.
public class Test
{
int a;
public void testMethod(int a)
{
this.a = a;
//Here this.a is variable 'a' of this instance. parameter 'a' is parameter.
}
}
Generally the usage of 'this' is reserved for instance variables and methods, not class methods ...
"class methods cannot use the this keyword as there is no instance for
this to refer to..."
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Here's a trivial example ...
public class Person {
private String name;
private int age;
private double weight;
private String height;
private String gender;
private String race;
public void setName( String name ) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge( int age) {
this.age = age;
}
public int getAge(){
return this.age;
}
public void setWeight( double weight) {
this.weight = weight;
}
public double getWeight() {
return this.weight;
}
public void setHeight( String height ) {
this.height = height;
}
public String getHeight() {
return this.height;
}
public void setGender( String gender) {
this.gender = gender;
}
public String getGender() {
return this.gender;
}
public void setRace( String race) {
this.race = race;
}
public String getRace() {
return this.race;
}
public void displayPerson() {
System.out.println( "This persons name is :" + this.getName() );
System.out.println( "This persons age is :" + this.getAge() );
System.out.println( "This persons weight is :" + this.getWeight() );
System.out.println( "This persons height is :" + this.getHeight() );
System.out.println( "This persons Gender is :" + this.getGender() );
System.out.println( "This persons race is :" + this.getRace() );
}
}
And for an instance of a person ....
public class PersonTest {
public static void main( String... args ) {
Person me = new Person();
me.setName( "My Name" );
me.setAge( 42 );
me.setWeight( 185.00 );
me.setHeight( "6'0" );
me.setGender( "Male" );
me.setRace( "Caucasian" );
me.displayPerson();
}
}
In case of member variable and local variable name conflict, this key word can be used to refer member variable like,
public Loan(String type, double interest){
this.type = type;
this.interest = interest;
}
if you have knowladge about c,c++ or pointers, in that language this is a pointer that points object itself. In java everything is reference. So it is reference to itself in java. One of the needs of this keyword is that:
Think that this is your class
public class MyClass
{
public int myVar;
public int myMethod(int myVar)
{
this.myVar = myVar; // fields is set by parameter
}
}
If there is not this keyword you it is confused that this is paramter or class field.When you use this.myVar it refers field of this object.
I would like to modify your language. The this keyword is used when you need to use class global variable in the constructors.
public class demo{
String name;
public void setName(String name){
this.name = name; //This should be first statement of method.
}
}
this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
One more thing that should be in mind is that this keyword might be the first statement of your method.
This is used in java. We can use in inheritance & also use in method overloading & method overriding. Because the actual parameter or instance variable name has same name then we can used this keyword complsary . But some times this is not same as when we can not use this keyword complsary.....
Eg:- class super
{
int x;
super(int x)
{
this.x=x
}
}

toString method

I want to add a toString method in the Item class that returns the title of the item in there.
I have need make sure that the toString method in the DVD class calls the toString method in Item so that it can return a string that contains both the title and the director.
Item is the superclass and DVD is the subclass.
public class Item
{
private String title;
private int playingTime;
private boolean gotIt;
private String comment;
public Item(String theTitle, int time)
{
title = theTitle;
playingTime = time;
gotIt = false;
comment = "<no comment>";
}
// Getters and setters omitted
public void print()
{
System.out.print(title + " (" + playingTime + " mins)");
if(gotIt) {
System.out.println("*");
} else {
System.out.println();
}
System.out.println(" " + comment);
}
}
public class DVD extends Item
{
private String director;
public DVD(String theTitle, String theDirector, int time)
{
super(theTitle, time);
director = theDirector;
}
// Getters and setters omitted
public void print()
{
System.out.println(" director: " + director);
}
}
Item toString:
public String toString()
{
return title;
}
DVD toString:
public String toString()
{
return super.toString() + " director: " + director;
}
Also, I don't know what you're trying to do with this but I would put those print() methods in these classes.
You will be better of returning the string representation and printing it somewhere else (with this you can test this class without mocking System.out)
Cheers
A toString method is already defined in each Java class (it inherits the toString of Object). But it will return a practically meaningless value (AFAIR, the internal address/id of the instance within the JDK - I might be wrong).
What you need to do is to override that method and make it return a String that is the title of the Item. For the DVD class, you have to override toString and make it a string made up of the concatenation of the title and director.
For the Item class, your method should look something like this:
public String toString(){
return this.title;
}
You should be able to use the same idea to implement toString for DVD.

Categories