Cameron said... Here's an assignment for you. This is important to do, because it will really hit where you're getting frustrated - working with methods, both creating them and passing values to them. Give it a try!
I didn't compile the code in the examples, so you might want to make sure I haven't missed a semi-colon or anything. Regardless, the objective remains the same: create the methods that I've asked for, and write some code that invokes the methods by passing in the appropriate objects! This will be eye-opening for you.
****************************
Let's look at three core shapes: Circle, Point and Rectangle.
Here's how we create them:
Circle drum = new Circle(2);
Circle life = new Circle(10);
Point ed = new Point(0,0);
Point pelee = new Point(5,5);
Rectangle r1 = new Rectangle(2,3);
Rectangle r2 = new Rectangle(5,4);
If I wanted to just print out the area of a Circle, I could create a method like this:
public class PracticeMethods {
public void printCircleArea(Circle c) {
System.out.println("The area of the circle you passed me is: " + c.getArea();
}
}
To run this code, I could write a class like this:
public class PMRunner {
public static void main(String args[]) {
Circle drum = new Circle(2);
PracticeMethods pm = new PracticeMethods(); //create an instance
pm.printCircleArea(drum); //pass an instance of a Circle to the method.
}
}
When the PMRunner executes, it will print out: The area of the circle you passed me is: 6
So, here you see how to code a class that has a method that takes an argument. (The PracticeMethods class)
And you also see how to create an instance of a class, and call one of the instance methods, while also passing in an argument of the proper type.
Question: Why does the printCircleArea return void and not a String? Doesn't the method return a String?
In the PracticeMethods class, create the following methods:
compareCircleToCircle - it takes two circles as arguments. It returns true or false depending on whether the two circles have the same area.
comparePointToCircle - it is passed in a Point and a Circle. It prints out how much bigger the area of the circle is than the area of the point.
compareCircleToSquare - it is passed in a Circle and a Square. It returns a String that says "The circle is bigger than the square" or "The square is bigger than the circle" or "The circle and square are the same size."
compareSquareToSquare - it is passed in two Squares, and returns a boolean value indicating if the first square is bigger than the second. It also returns the difference in the sizes of the two squares.
12 comments:
I got circle area to compare to circle area. Thanks for the help with returning the boolean value, Cam.
Circle Class
public class Circle {
public int radius;
public Circle(int r) {
radius = r;
}
public int getArea() {
return radius * radius * 3;
}
}
PMRunner Class
public class PMRunner {
public static void main(String args[]) {
Circle drum = new Circle(3);
Circle life = new Circle(5);
System.out.println("Circle drum radius " + (drum.radius));
System.out.println("Circle life radius " + (life.radius));
PracticeMethod pm = new PracticeMethod(); // create an instance
pm.printCircleArea(drum, life); // pass an instance of a Circle to the
// method.
pm.isAreaEqual(drum, life);
boolean comparisonValue = pm.isAreaEqual(drum, life);
System.out.println("Do the circles have the same area? "
+ comparisonValue);
}
}
Practice Method Class
public class PracticeMethod {
public void printCircleArea(Circle b, Circle c) {
System.out.println("The area of the circle named " + b
+ " you passed me is: " + b.getArea());
System.out.println("The area of the circle named " + c
+ " you passed me is: " + c.getArea());
}
public boolean isAreaEqual(Circle d, Circle l) {
if (d.getArea() != l.getArea()) {
return false;
}
return true;
}
}
I have gotten circle to compare to square (hey Cam, here is an assignment for you!!!). Without using doubles or ABS statements, try to find an area of a circle that is equal to the area of a square. I will only include PMRunner and CompareCircleToSqaure methods:
public class PMRunner {
public static void main(String args[]) {
// Declare shapes (Custom constructors)
Circle drum = new Circle("DRUM", 1);
Circle life = new Circle("LIFE", 3);
Point point = new Point(1, 1);
Square squareone = new Square("SQUARE 1", 5);
Square squaretwo = new Square("SQUARE 2", 4);
// Print out to console object(shape) properties
System.out.println("Circle DRUM radius is: " + (drum.radius));
System.out.println("Circle LIFE radius is: " + (life.radius));
System.out.println(squareone.name + "'s side length is: "
+ (squareone.side));
System.out.println(squaretwo.name + "'s side length is: "
+ (squaretwo.side));
// Print out Circles area's
CirclePracticeMethod cpm = new CirclePracticeMethod(); // create an
// instance
cpm.printCircleArea(drum, life); // pass an instance of a Circle to the
// method.
// Compare Circles area's, notify client if Circles have/do not have
// same area's
cpm.isCircleAreaEqual(drum, life);
boolean comparisonValue = cpm.isCircleAreaEqual(drum, life);
System.out.println("Do the circles have the same area? "
+ comparisonValue);
// Notify client Point's have no area
PointPracticeMethod ppm = new PointPracticeMethod();
String s = ppm.getArea(point);
System.out.println(s);
// Calculate Square Area
SquarePracticeMethod spm = new SquarePracticeMethod();
spm.printSquareArea(squareone, squaretwo);
// Compare Circle to Square
CompareCircleToSquare ccts = new CompareCircleToSquare();
String s2 = ccts.compareShapes(drum, squareone);
System.out.println(s2);
}
}
public class CompareCircleToSquare {
public int squarearea;
public int circlearea;
public String compare;
public String compareShapes(Circle c, Square s) {
circlearea = c.getCircleArea();
squarearea = s.getSquareArea();
if (circlearea > squarearea) {
String circlebigger = "The circle named DRUM is bigger than the square named SQAURE 1";
compare = circlebigger;
}
if (circlearea == squarearea) {
String same = "The circle named DRUM and the square named SQUARE 1 are equal";
compare = same;
}
if (circlearea < squarearea) {
String squarebigger = "The square named SQUARE 1 is bigger than the circle named DRUM";
compare = squarebigger;
}
return compare;
}
}
Very, very interesting.
You've stumbled upon an interesting design point. You have the squareArea, circleArea and compare properties defined as instance variables of the CompareCircleToSquare class. Very interesting.
So, should they be? Clearly, by doing this, you can get the code to work. So, from that perspective, it works fine. It's one approach.
But think about this: are those properties used anywhere in the CompareCircleToSquare class other than the compareShapes method? It's a pretty significant step to declare properties inside the class but not inside a method. It means they are 'instance level properties' and that is a pretty special designation in Java.
So, if you can code the method without declaring the properties as class-level or instance-level properties, then that's a better approach. Look at this:
****************
public class CompareCircleToSquare {
/* No instance variables/properties defined.*/
public String compareShapes(Circle c, Square s) {
/* local variables. Notice: NO ACCESS MODIFIER
This looks really clean. Someone can look at the top of the method and know right away what the important variables being used are.*/
int squarearea;
int circlearea;
String compare;
/* Now code the method like usual! */
circlearea = c.getCircleArea();
squarearea = s.getSquareArea();
if (circlearea > squarearea) {
String circlebigger = "The circle named DRUM is bigger than the square named SQAURE 1";
compare = circlebigger;
}
if (circlearea == squarearea) {
String same = "The circle named DRUM and the square named SQUARE 1 are equal";
compare = same;
}
if (circlearea < squarearea) {
String squarebigger = "The square named SQUARE 1 is bigger than the circle named DRUM";
compare = squarebigger;
}
return compare;
}
}
****************
I love these types of 'teachable moments' because it goes beyond simply 'what works' and into a discussion of 'whats best and why.' Good stuff!
We need a friggin' blog application that formats code properly!
public String compareShapes(Circle c, Square s) {}
Now look at that method. Isn't it handsome?
I can look at that RIGHT AWAY and know that I need to pass in a Circle and a Square, and in that order exactly. I don't pass in a Square and then a Circle, I don't pass in a String and a Square, I don't pass in a Point and a Triangle. I pass in an instance of a Circle and an instance of a Square, and in that order exactly.
Compare these two:
public String compareShapes(Circle c, Square s) {...}
public String compareShapes(c, s) {...}
You've been writing methods like the second one, but notice how the second one, which of coursewon't compile, doesn't let someone who might be calling it know what types of objects need to be passed in. What is a 'c'??? What is a 's'???
When you write a method, the intention is that some other program, written by someone else, will be 'calling it' or 'invoking it.' As a result, they need to know what types of instances to pass into it. So when you write a method that takes arguments, you must always state explicitly what the TYPE is of the arguments are. The variable name you provide is only really important to you, inside the method, but the DATA TYPE is needed by anyone who wants to invoke it.
This is correct:
public String compareShapes(Circle c, Square s) {...}
This is always wrong:
public String compareShapes(c, s) {...}
The thing is, at about this point, you should be able to just look at the second method declaration and know that something just isn't right about it. Even if you don't know right away what the problem is, just your knowledge of the language and syntax should be triggering some spidey senses. It really is just like learning a foreign language - you slowly start to instinctively pick up on things that are right and wrong.
Ok, I know there is a lot of redundant code being posted here, but I feel it important to post my code at each stage for tutoring reasons. Therefore . . . . here is the updated PMRunner Class and the new CompareSquareToSquare Class, with output.
PMRUNNER:
public class PMRunner {
public static void main(String args[]) {
// Declare shapes (Custom constructors)
Circle drum = new Circle("DRUM", 3);
Circle life = new Circle("LIFE", 3);
Point point = new Point(1, 1);
Square squareone = new Square("SQUARE 1", 1);
Square squaretwo = new Square("SQUARE 2", 2);
// Print out to console object(shape) properties
System.out.println("Circle DRUM radius is: " + (drum.radius));
System.out.println("Circle LIFE radius is: " + (life.radius));
System.out.println(squareone.name + "'s side length is: "
+ (squareone.side));
System.out.println(squaretwo.name + "'s side length is: "
+ (squaretwo.side));
// Print out Circles area's
CirclePracticeMethod cpm = new CirclePracticeMethod(); // create an
// instance
cpm.printCircleArea(drum, life); // pass an instance of a Circle to the
// method.
// Compare Circles area's, notify client if Circles have/do not have
// same area's
cpm.isCircleAreaEqual(drum, life);
boolean comparisonValue = cpm.isCircleAreaEqual(drum, life);
System.out.println("Do the circles have the same area? "
+ comparisonValue);
// Notify client Point's have no area
PointPracticeMethod ppm = new PointPracticeMethod();
String s = ppm.getArea(point);
System.out.println(s);
// Calculate Square Area
SquarePracticeMethod spm = new SquarePracticeMethod();
spm.printSquareArea(squareone, squaretwo);
// Compare Circle to Square
CompareCircleToSquare ccts = new CompareCircleToSquare();
String s2 = ccts.compareCircleShapes(drum, squareone);
System.out.println(s2);
// Compare Square to Square
CompareSquareToSquare csts = new CompareSquareToSquare();
boolean squareonebigger = csts.isSquareOneBigger(squareone, squaretwo);
System.out
.println("Is the first Square bigger than the second Square? "
+ squareonebigger);
// if (squareonebigger = true){
}
}
------------------------------------------------
COMPARE SQUARE TO SQUARE
public class CompareSquareToSquare {
public boolean isSquareOneBigger(Square squareone, Square squaretwo) {
int sq1area;
int sq2area;
boolean b = false;
sq1area = squareone.getSquareArea();
sq2area = squaretwo.getSquareArea();
if (sq1area > sq2area) {
b = true;
}
return b;
}
// public int squareSizeDifference() {
// }
}
------------------------------------------------
FALSE CONDITION OUTPUT
Circle DRUM radius is: 3
Circle LIFE radius is: 3
SQUARE 1's side length is: 1
SQUARE 2's side length is: 2
The area of the circle named DRUM you passed me is: 27
The area of the circle named LIFE you passed me is: 27
Do the circles have the same area? true
Points have no area, even a point at 1 and 1.
The area of the square named SQUARE 1 is: 1
The area of the square named SQUARE 2 is: 4
The circle named DRUM is bigger than the square named SQUARE 1
Is the first Square bigger than the second Square? false
------------------------------------------------
TRUE CONDITION OUTPUT
Circle DRUM radius is: 3
Circle LIFE radius is: 3
SQUARE 1's side length is: 3
SQUARE 2's side length is: 2
The area of the circle named DRUM you passed me is: 27
The area of the circle named LIFE you passed me is: 27
Do the circles have the same area? true
Points have no area, even a point at 1 and 1.
The area of the square named SQUARE 1 is: 9
The area of the square named SQUARE 2 is: 4
The circle named DRUM is bigger than the square named SQUARE 1
Is the first Square bigger than the second Square? true
You will notice I made the changes to the class level variables and "relocated" them to inside the method. I ask the question, then, what is the need for the "parent" class when all declaring, initializing and conditioning is done at the instance method level?
Very clean. Very clean.
"Parent?" Ohh....You can't use that word! You can only use that word when talking about inheritance with the keywords extends or implements. Really, you mean 'the surrounding class' that contains the method. Well, all methods must go inside a class. That's a rule. But yes, classes are interesting because they have properties, and if a class doesn't have any properties, well, it's not very interesting! At least, the instances of the class aren't interesting. This will lead us into the discussion of the keyword static, which is a special keyword you can use to indicate that methods are just worker methods that don't work on any instance variables, and instead, have all of the data they need passed into them from the calling program.
Ok. Drum roll. Yer lucky it is 1:15am. . . . .
------------------------------------------------
PMRUNNER
public class PMRunner {
public static void main(String args[]) {
// Declare shapes (Custom constructors)
Circle drum = new Circle("DRUM", 3);
Circle life = new Circle("LIFE", 3);
Point point = new Point(1, 1);
Square squareone = new Square("SQUARE 1", 6);
Square squaretwo = new Square("SQUARE 2", 3);
// Print out to console object(shape) properties
System.out.println("Circle DRUM radius is: " + (drum.radius));
System.out.println("Circle LIFE radius is: " + (life.radius));
System.out.println(squareone.name + "'s side length is: "
+ (squareone.side));
System.out.println(squaretwo.name + "'s side length is: "
+ (squaretwo.side));
// Print out Circles area's
CirclePracticeMethod cpm = new CirclePracticeMethod(); // create an
// instance
cpm.printCircleArea(drum, life); // pass an instance of a Circle to the
// method.
// Compare Circles area's, notify client if Circles have/do not have
// same area's
cpm.isCircleAreaEqual(drum, life);
boolean comparisonValue = cpm.isCircleAreaEqual(drum, life);
System.out.println("Do the circles have the same area? "
+ comparisonValue);
// Notify client Point's have no area
PointPracticeMethod ppm = new PointPracticeMethod();
String s = ppm.getArea(point);
System.out.println(s);
// Calculate Square Area
SquarePracticeMethod spm = new SquarePracticeMethod();
spm.printSquareArea(squareone, squaretwo);
// Compare Circle to Square
CompareCircleToSquare ccts = new CompareCircleToSquare();
String s2 = ccts.compareCircleShapes(drum, squareone);
System.out.println(s2);
// Compare Square to Square
CompareSquareToSquare csts = new CompareSquareToSquare();
boolean squareonebigger = csts.isSquareOneBigger(squareone, squaretwo);
System.out
.println("Is the first Square bigger than the second Square? "
+ squareonebigger);
CompareSquareToSquare sd = new CompareSquareToSquare();
int sizedifference = sd.squareSizeDifference(squareone, squaretwo);
System.out.println("SQUARE 1 is bigger than SQUARE 2 by "
+ sizedifference + " units.");
// Create an object with two separate data types
TypeHandler th = new TypeHandler(squareonebigger, sizedifference);
System.out.println("The object named TypeHandler has two return data type values, which are: "+th.b+" and "+th.sizedif);
}
}
-----------------------------------------------
TYPEHANDLER
public class TypeHandler {
boolean b;
int sizedif;
public TypeHandler(boolean squareonebigger, int sizedifference) {
b = squareonebigger;
sizedif = sizedifference;
return;
}
}
-----------------------------------------------
PROGRAM OUTPUT
Circle DRUM radius is: 3
Circle LIFE radius is: 3
SQUARE 1's side length is: 6
SQUARE 2's side length is: 3
The area of the circle named DRUM you passed me is: 27
The area of the circle named LIFE you passed me is: 27
Do the circles have the same area? true
Points have no area, even a point at 1 and 1.
The area of the square named SQUARE 1 is: 36
The area of the square named SQUARE 2 is: 9
The square named SQUARE 1 is bigger than the circle named DRUM
Is the first Square bigger than the second Square? true
SQUARE 1 is bigger than SQUARE 2 by 27 units.
The object named TypeHandler has two return data type values, which are: true and 27
For the love of god . . . . no more shapes . . . . please, no more shapes. Next assignment??? Or, shall you rip my code apart and tell me how bad it is? Come on, I can take it . . . .
First off, there’s a big leap of learning here.
The requirement was to return ‘two things’ from the given method, but of course, a method can only return ‘one thing’, so how do you return both a Boolean and an int from a method if a method can only return ‘one thing?’ Well, you create a custom class of your own, you package those ‘two things’ up inside of the class, and you pass around instances of that class.
There are a few nice things here. First, the TypeHandler has two properties, and as such, it makes sense that it should have a consturctor that takes the same two properties:
public TypeHandler(boolean squareonebigger, int sizedifference) {…}
Now, one thing is the fact that constructors don’t return anything. I’m surprised it even compiles with that return on the end, but regardless, don’t ever do that. As a general rule, constructors and void methods shouldn’t have returns in them!
public class TypeHandler {
boolean b;
int sizedif;
public TypeHandler(boolean squareonebigger, int sizedifference) {
b = squareonebigger;
sizedif = sizedifference;
return;
}
}
But there is a bit of a problem. The requirement was to have a method that returns two pieces of data. You don’t do this in your code. You do this:
TypeHandler th = new TypeHandler(squareonebigger, sizedifference);
System.out.println("xyz: " + th.b + " and "+ th.sizedif);
That’s not calling a method, but instead, that’s calling a constructor.
Instead, you should do this:
CompareSquareToSquare sd = new CompareSquareToSquare();
TypeHandler th = sd.camsSquareSizeDifference(squareone, squaretwo);
Notice how the method is returning an instance of the TypeHandler, as opposed to calling the constructor directly in the code? The method would look like this:
public TypeHandler camsSquareSizeDifference(Square boy, Square pegs) {
int sizedifference = 0;
boolean squareonebigger = false;
/* do stuff in here to properly initialize squareonebigger and sizedifference */
TypeHandler typeHandlerInstance = new TypeHandler(squareonebigger, sizedifference);
return typeHandlerInstance;
}
Notice how this method is creating the instance of the TypeHandler, and returning the instance?
By the way, it’s always nice to have methods that create objects for us, without forcing the calling program to call the constructor directly. These types of methods are often called ‘factory methods’ because their job is to create and pump out instances of classes.
From what you have said here, I believe I am still confusing methods and constructors. Any small, easy side assignments that would pound the difference between a constructor and a method in to my head???
Post a Comment