How public members of a class causes havoc in java? - java

How public members of a class causes havoc in java? Can someone please explain with example? I tried to create such situation but couldn't succeed. I simply found them equivalent to 'protected' access modifier.

It allows invalid values, breaking encapsulation.
public class Clock {
public int hours;
public int minutes;
}
Then, in unrelated code...
Clock clock = new Clock();
clock.hours = 42;
clock.minutes = 99;
Having them private with setter and getter methods allows encapsulation to enforce proper values.
public class Clock {
private int hours;
private int minutes;
public void setHours(int hours) {
if (hours < 0 || hours > 23) throw new IllegalArgumentException("bad range");
this.hours = hours;
}
// Likewise for "setMinutes" method.
}
Here's a tutorial page on encapsulation in Java on encapsulation's benefits. Quoting:
The fields of a class can be made read-only or write-only.
A class can have total control over what is stored in its fields.
The users of a class do not know how the class stores its data. A
class can change the data type of a field, and users of the class do
not need to change any of their code.

I believe it all depends on the application/program that you design.
Declaring the members as private definitely does have advantages.
But on the other hand,
If you design say a Point Class, which the users would be inheriting
and using it to draw various shapes, square, rectangle, circle, you
might think of keeping the memebers x, y, z as public.
Example:
class Point{
public double x = 0.0;
public double y = 0.0;
public double z = 0.0;
}
The advantage here would be; the classes Rectangle, Square, can access the points directly
say;
class Square extends Point{
private Point p;
p.x = 4.0;
p.y = 10.0;
p.z = 0;
// Instead of using double x = p.getX(); double p.setX(5.0);
}
Hope this helps.
Read the below articles; it should help you.
Source 1
Source 2
Source 3

Related

Multiple seperate objects constructed from same class

Beginner java programmer
I created a class Car
public class Car {
private static final double MILES_PER_YEAR = 20000;
private static final double GAS_PRICE = 2.50;
private static double pricePerYear;
private static double totalPrice;
public Car(double initialPrice, double milesPerGallon) {
pricePerYear = (MILES_PER_YEAR / milesPerGallon);
totalPrice = initialPrice;
}
Then in my main function I construct two Car objects
Car civic = new Car(22000, 35.5);
Car prius = new Car(27135, 55.5);
However, when I check attributes of these objects with civic.getTotalPrice() and prius.getTotalPrice() they're always the same. The second object contruction always overrides the first and when I construct them like I did above ^^ and get both prices, they both return 27135. This happens the same way vice versa if I define them like this
Car prius = new Car(27135, 55.5);
Car civic = new Car(22000, 35.5);
For the segment above, the return for both civic.getTotalPrice() and prius.getTotalPrice() comes out as 22000
I think the issue has something to do with keywords like public, private, static, void, final, etc. as I do not full yunderstand what they mean yes, but I'm confused as to why the code still runs if it is a keyword problem like that.
My main goal is to compare the seperate objects' attributes and modify them individually if that helps anyone understand where I was going with this.
Make the member variables non-static:
public class Car {
private static final double MILES_PER_YEAR = 20000;
private static final double GAS_PRICE = 2.50;
private double pricePerYear;
private double totalPrice;
public Car(double initialPrice, double milesPerGallon) {
pricePerYear = (MILES_PER_YEAR / milesPerGallon);
totalPrice = initialPrice;
}
}
static specifically means that members don’t belong to one specific instance and are instead shared by all of them. This makes sense for values such as MILES_PER_YEAR and GAS_PRICE: these are always the same, regardless of what car you define.

Is it a good practice to have parameter that is a global variable?

I am an AP java student and while working on a project I wondered if it is a good practice to have a parameter that is a global variable. If you're wondering why I would want to do that well is so I wouldn't have to do this:
public class Circle {
private DrawingTool pen;
private SketchPad paper;
private double myX;
private double myY;
private double myWidth;
private double myHeight;
public Circle(double x, double y, double width, double height){
paper = new SketchPad(500,500);
pen = new DrawingTool(paper);
x = myX; //I don't want to have to assign this every time
y = myY; //like here
width = myWidth; // and here
height = myHeight; // and here
}
}
is it allowed to just do the following:
public Circle(double myX, double myY, double myWidth, double myHeight){
paper = new SketchPad(500,500);
pen = new DrawingTool(paper);
}
}
and every time I pass the arguments to the parameter they will automatically be assigned to the global variables?
and every time I pass the arguments to the parameter they will automatically be assigned to the global variables?
No. There's nothing within Java which will make the "parameter to instance variable" (which isn't really "global") assignment automatic. Many IDEs have the ability to generate the code for you, but it does need to be there.
An object stores its state in fields (variables in some programming languages) and exposes its behavior through methods (functions in some programming languages). Methods operate on an object's internal state and serve as the primary mechanism for object-to-object communication. Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.
Source: What Is an Object?

Call a method from another class(not main class)

How to call distanceTo(Point p) of Point.java into Point2.java under a method takes no parameter? There should be a way but I cannot find from my materials. Could anybody help me? It has been doing 2 days. Please help...
---------------------Point.java---------------------------------
public class Point{
private int x;
private int y;
//x and y coordinates as parameters
public Point(int x, int y){
this.x = x;
this.y = y;
}
//I want to call this method by calling a method which taken no parameter in Point2.java.
public double distanceTo(Point p){
return Math.sqrt(((x - p.x) * (x - p.x)) + ((y - p.y) * (y - p.y)));
}
}
---------------------ClonePoint.java---------------------------------
public class ClonePoint{
private int a;
private int b;
//x and y coordinates as parameters
public ClonePoint(int a, int b){
this.a = a;
this.b = b;
}
//I failed with this way. Can anybody correct me?
public double measureDistance(){//it should be takes no parameter.
return distanceTo(ClonePoint p)
}
}
----------------------PointDriver.java-----------------------------
public class PointDriver {
public static void main(String [] args) {
Point2 nn = new Point2(11, 22);
Point2 mm = new Point2(33, 44);
System.out.println(nn.distanceTo(mm)); //I succeeded with this!
System.out.println(nn.measureDistance(mm)); //But I got an error illegal start of expression
}
}
#Evan a class is a generalized container for your things. A car, a person, a point (in your case).
Everytime you want to "create" one or more object of your defined class, you instantiate them:
Person evan = new Person();
Person rob = new Person();
both of us are person, you don't really need to define class Person1 and Person2!
And in a class you should define the methods used to "relate" to other similar objects.
For example:
// In Person.java
public void greet(Person p) {
System.out.println("My name is "+this.name+". Nice to meet you +"p.getName());
}
// In main
rob.greet(evan); // it now gives compile errors of course but take the point :P
What you want to achieve is to create a better and more complete Point class with all the methods you want to use. In the end, just initialize more Point objects (same class!) in your main and play with them.
Hope it helps :)
EDIT
Ok, perhaps I've got what your homework wants you to perform.
A "parameter-less" method measureDistance() should make you wonder one important thing: "distance FROM which point????".
Obviously, if the function takes no parameters all the information needed to that calculus must be in the object which calls it. Don't you think?
So, you probably want to achieve a secondary class (if you really need to define it as Point2 it's ok, but change that name because it's confusing) which can take a Point in its constructor (saving this information in itself) and then use that Point to measure distance from it.
Example
public class Point2{
private int a;
private int b;
private Point startingPoint;
public Point2(int a, int b, Point p){
this.a = a;
this.b = b;
startingPoint = p;
}
// Computes the distance from starting point to this
public double measureDistance(){//it takes no parameter.
return startingPoint.distanceTo(a, b);
}
/*
if you can't edit distanceTo() it gets a little verbose but you must create a
Point with Point2 coordinates - remember this example when you will study Inheritance
public double measureDistance() {
Point endingPoint = new Point(a, b);
return startingPoint.distanceTo(endingPoint);
}
*/
}
First, it is not good idea to duplicate a class that does the same thing because you are doing extra unneeded work. Second, if you make various point types, you are loosing the advantage of seamless compatibility between them.
Then, if you want to call method from other class you can do it like this:
NameOfOtherClass.SomeMethod()
But you have to declare the SomeMethod in the other class as static...
public static double SomeMethod() { ... };
But then you can't use the method to access the data of your concrete points you have created in your code, so any data should be put into parameters.
If you want to do it your way, you have to just add a parameter to public double measureDistance()
function so the function has access to another point to measure distance to.

Accessing class A from class B

I am doing this piece of school work. its about bin packing problem but its a bit modified about a trolley. There can be two or more piles inside the trolley. What I have done so far is made a parcel class and pile class. There are few rules to this that i need to follow. One of them is that when i put parcel (width 3) inside pile i cant put parcel (width 4) on top of it.
Yes i will have trolley class, pile class and parcel class.
What i am trying to do here make a function inside the pile class that changes the Width of the pile to whatever the width of the Parcel is that was just put in. How do I access parcel width from pile class ? will it just be getW() ? much appreciated the help. Or should i do this inside the trolley class ? not exactly sure how to implement this.
public class Parcel {
private int H;
private int W;
private int customer;
Parcel(int inH, int inW, int inCustomer){
this.H = inH;
this.W = inW;
this.customer = inCustomer;
}
public int setH(){
int x = (int )(Math.random() * 50 + 1);
return x;
}
public int setW(){
int y = (int )(Math.random() * 100 + 1);
return y;
}
public int getW(){
return W;
}
public int getH(){
return H;
}
Your setW() is misnamed. It should be randomizeWidth(). What you should consider doing is to give the above class a valid width setter method, setWidth(int width) that set's the W variable (rename it to width to comply with Java naming conventions -- variable names should begin with a lower-case letter) so that outside classes can call the method and set the width.
Pile should likewise have valid setters and getters for its width and other properties. Pile can then call the Parcel methods above and use the information to set its width. If Pile object holds Parcel objects, then it's probably better for Pile to set its own width based on the widths of the Parcel objects it holds. So my suggestion is that Parcel not set a Pile's width.
Assuming that pile has a field of type parcel, you can just call the getter.
public class Pile
{
Parcel parcel;
public Pile()
{
//instanciate parcel here;
}
public void someMethod
{
int w = this.parcel.getW();
}
}

Lesson 16 - Gas Mileage - Multiple Classes Project

~~~Update: Solved! Thanks everyone!~~~
I'm working on a project from the Blue Pelican Java book, lesson 16 project Gas Mileage. It asks to create two classes, one is Automobile which holds the methods I will work with. The other class, Tester, is the main class. Every time I run the Tester class, it returns a value of -Infinity. I can't figure out why, other than that I've singled out the problem is in the Automobile class at line 14 in the takeTrip method. When I leave that method out of the Tester class, it returns the correct values.
This is the Automobile class:
public class Automobile
{
public Automobile(double m) // Accepts value m to the double mpg. Also declares
{
double mpg = m;
double gallons;
}
public void fillUp(double f) // Adds fuel to the tank
{
gallons += f;
}
public void takeTrip(double t) // Takes away fuel from the tank depending upon how many miles are driven
{
gallons -= t / mpg; // Not sure how to do this line. For some reason, when I reference mpg, the output of Tester is "-infinity". Shouldn't it do gallons = gallons - (miles driven / mpg)?
}
public double reportFuel() // Returns value of how much fuel is left in tank
{
double r = gallons;
return r;
}
public double mpg;
public double gallons;
}
And this is the Tester class:
public class Tester
{
public static void main(String args[])
{
Automobile myBmw = new Automobile(24); // Passes constructor argument of 24 mpg
myBmw.fillUp(20); // Adds 20 gallons to fillUp method
myBmw.takeTrip(100); // Takes away the fuel used for 100 miles using the takeTrip method
double fuel_left = myBmw.reportFuel(); // Initializes fuel_left to the method reportFuel
System.out.println(fuel_left);
}
}
Any help is appreciated, thanks!
-AJ
You constructor doesn't need the 'double' identifier. Here you are creating a new variable also called mpg, which is forgotten after the constructor completes. Instead use this:
public Automobile(double m) // Accepts value m to the double mpg. Also declares
{
mpg = m;
}
This is the problem:
public Automobile(double m) // Accepts value m to the double mpg. Also declares
{
double mpg = m;
double gallons;
}
This is declaring a local variable called mpg, rather than changing the value of the instance variable for the object. (The instance variables are declared at the bottom of the class.) It's then declaring another local variable called gallons which isn't assigned any value. At the end of the constructor, the instance variables gallons and mpg will both be zero - which means you'll be dividing by zero in the takeTrip method - so you're subtracting "infinity gallons" from the fuel tank, leading to your final result. Your constructor should look like this instead:
public Automobile(double m)
{
this.mpg = m;
}
or just:
public Automobile(double m)
{
mpg = m;
}
If you're still unsure about local variables and instance variables after this, see if there's anything earlier in the book which might help you. (By lesson 16 I'd expect it to have been covered...)
In your Automobile c'tor, you're currently creating a local variable called mpg, instead of changing the class member. All there should be in that function is mpg = m; (the second line does nothing).
Currently, mpg (the member) is automatically initialized to 0, and then t/mpg is infinity, and when you take that away from some finite number, you get -infinity.
By the way, in reportFuel(), you could just as well just write return gallons;, without declaring r.
public class Automobile {
private double mpg = 0; //need to handle the division by 0 if you
//initialize it to 0
private double gallons = 0;
public Automobile(double m, double g)
{
mpg = m;
gallons = g;
}
Why are again declaring your attributes inside your constructor where as you have already declared them in your class. Actually the attributes you are declaring inside the constructor will not persist after the execution of the method ends (in this case the constructor). So though you are trying to initialize the attributes of your class you are actually not doing this.
So in your constructor try this
mpg=m
gallons=0
I think the other methods are fine. Another thing try to keep those attributes (mpg and gallons) private. Though the program will run without any error still you are violating the main thing of oop - encapsulation. cheers :)

Categories