Understanding classes and variables in java [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am new to Java and this was a example I found in the book I am reading.There are several things I do not understand in this code.Please help me to understand it.
/*
* CalculatorModel
* Encapsilates the data model used by the calculator Application
*/
public class CalculatorModel{
private double operand1;
private double operand2;
public void setOperand1(double value){
operand1=value;
}
public void setOperand2(double value){
operand2=value;
}
public double getOperand1(){
return operand1;
}
public double getOperand2(){
return operand2;
}
public String toString(){
String s = "operand 1=" + operand1 + "operand 2=" + operand2;
return s;
}
}
/*
* CalculatorHelper
* A class that performs mathematical functions for a calculator program
*/
public class CalculatorHelper{
private CalculatorModel calcModel;
public CalculatorHelper(){
calcModel=new CalculatorModel();
}
public void setOperand1(double value){
calcModel.setOperand1(value);
}
public void setOperand2(double value){
calcModel.setOperand2(value);
}
public double add(){
return calcModel.getOperand1()+calcModel.getOperand2();
}
public double subtract(){
return calcModel.getOperand1()-calcModel.getOperand2();
}
public double multiply(){
return calcModel.getOperand1()*calcModel.getOperand2();
}
public double divide(){
return calcModel.getOperand1()/calcModel.getOperand2();
}
}
Please help me to understand what is done by
private CalculatorModel calcModel;
public CalculatorHelper(){
calcModel=new CalculatorModel();
}
in the calculatorHelper class. Is calcModel a variable a variable of type CalculatorModel? What is the difference of having a object as a data type than a primitive data type to a variable?
If calcModel is a variable what is done by the line calcModel=new CalculatorModel();
I don't understand why it is important to have two classes as CalculatorModel and CalculatorHelper.
What is done with the method
public void setOperand1(double value){
calcModel.setOperand1(value);
}
in the helper class as there's already a setmethod in CalculatorModel class.
This is what I tried and what's wrong with this code?
public class Calculator{
private double num1,num2;
public void setValue1(double value1){
num1=value1;
}
public void setValue2(double value2){
num2=value2;
}
public double getValue1(){
return num1;
}
public double getValue2(){
return num2;
}
public double add(){
return getValue1()+getValue2();
}
public double subtract(){
return getValue1()-getValue2();
}
public double multiply(){
return getValue1()*getValue2();
}
public double divide(){
return getValue1()/getValue2();
}
}

"What is the difference of having a object as a data type than a primitive data type to a variable?"
Programming is all about data. Classes you can consider as complex data, and primitives as simple data. Say you have a class School
public class School {
}
What does school have? It has students. You can't represent a student with an of primitive types, because it just doesn't make sense for a student to be a double, int boolean, etc. So a student is another complex data type, like a school. So in order for the student to be represented as data contained by the school, you need a Student class also, which can hold the student's name, address and such
public class Student{
String firstName;
String lastName;
String address;
int age;
So to fully represent the student being in the school you use the has-a relationship, where School has-a Student
public class School {
Student student;
}
To delve even deeper, does a school only have one student? No, it should have many students. So you would represent that as a School having an array of Students
public class School {
Student[] students;
}
So in terms of data, you have a data tree like this now
School
Student
firstName
lastName
address
age
Student
firstName
lastName
address
age
This is the basic idea behind Object Oriented Programming. It's a lot easier to comprehend when you look at objects as actual physical objects. It makes it easier to understand the relationships.

Yes, your assumption that calcModel is a variable object of type CalculatorModel is right. when you say calcModel = new CalcModel(); it is actually creating another object in memory for storing the data that is to be stored(both operands) and storing the address of that object in calcModel. This way you can refer to object you created earlier. If you have worked with c earlier you can easily say calcModel is a pointer where as the object created is the data in the address located in the pointer.
The difference between a primitive type variable and object type variable is that the actual data that is to be stored in the variable is much more complex. For example the class CalculatorModel is a combination of two doubles... You can carry both operands as one entity by combining them(encapsulating) in a class. An object may also contain methods that can do some operations on the data stored in its member variables.
It is not necessary to have two classes, some people like it that way. I'm positively sure there is no need to create two classes in this case. Both can be merged as you have obviously did. Mind you there are no right and wrong ways to code, some ways of doing it are more preferable because they are more popular and avoids readability issues in long run. setOperand1() method is just using calcModel.setOperand1() so I don't see a necessity to have it done that way, calcModel.setOperand1 can be called directly from where ever setOperand1() is called. However, there can be case where you want to hide which function of setOperand1 is to be called or some complex operations are to be performed before calling calcModel.setOperand1. In such cases where you want to reduce burden for the callers of calcModel.setOperand1 by created setOperand1().
There is nothing wrong with the code. However you don't have to use getValue1() & getValue2() function in your add, subtract and other mathematical operations. you can simply say return num1+num2 Because, num1 & num2 are member variables of the same class.

private CalculatorModel calcModel;
public CalculatorHelper(){
calcModel=new CalculatorModel();
}
in the calculatorHelper class. Is calcModel a variable a variable of
type CalculatorModel ?What is the difference of having a object as a
data type than a primitive data type to a variable? If calcModel is a
variable what is done by the line calcModel=new CalculatorModel();
The variable calcModel is an instance of CalculatorModel, but is a class variable to the class CalculatorHelper. If you want to know about primitive data type vs object data type, check this article out. This line calcModel=new CalculatorModel(); is initializing the variable. You must do this in order to actually use the methods. Read more here.
I don't understand why it is important to have two classes as
CalculatorModel and CalculatorHelper.
There are cases where helper classes/methods are useful when it comes to separating large chunks of logic. Check this article out.
public void setOperand1(double value){
calcModel.setOperand1(value);
}
in the helper class as there's already a setmethod in CalculatorModel
class.
Yes, and it's calling that same exact set method but from the CalculatorHelper class.
This is what I tried and what's wrong with this code?
There seems to be nothing wrong with the code. I'm assuming you're using it properly from the main method (or whatever method you're using the class in).

This is essentially a Delegate Pattern by which the author has implemented the Calculator.
The Calculator serves the abstraction of the real-life Calculator.
By providing the helper/delegate class , I separate the behavior of the object.I am free to write my own implementation of add / subtract using a helper class. Calculator will serve as the Model of your calculations.
Consider this , If you try to modify the behavior you need to change the whole Calculator class and distribute it to the Client. However , I don't have to modify the Calculator but only the Helper which the client does/might not ship.
There is nothing wrong in what you have done - but consider this - what if you want to have Single instance of the Calculator - you can control instantion using helper class (in this case)

private CalculatorModel calcModel;
public CalculatorHelper(){
calcModel=new CalculatorModel();
}
is composition which is used here to separate concerns. The CalculatorHelper's concern is to know how to do addition, substraction, .. while the CalculatorModel knows the values, how to provide them to the outside and how to store them.
CalculatorHelperhas therefore an instance ofCalculatorModel` to which it can delegate all the things it does not know about. E.g.
public void setOperand1(double value){
calcModel.setOperand1(value);
}
The overall design is still questionable. First of all is it a bad encapsulation of a "calculator" because none of math operation reflect back to the model in any way. There needs to be a third class (CalculatorHelperHelper?) that knows how to deal with more than two operands.
It is also questionable whether or not a CalculatorModel should have two values at once. Two separate value objects would IMO make a lot more sense and would result in more modular code that would also be easier to understand as composition of objects.
The last point in this example is that encapsulating "storage" of values into CalculatorModel does not provide any real benefit here. It would if there was some kind of database backend or otherwise "complicated" logic that does not belong into CalculatorHelper. I would have taken more or less your approach in a simple real world scenario. Your code is not wrong. It's just a different approach.
The code in the context of the book and given that it is an example to show some design techniques is ok for that purpose. I would just do it very much different if I was to write a calculator. OO design is on the other hand not right or wrong and people can argue a lot about what good design is.

Related

How to write custom casting method in Java

I have a Java class that has a few members. I want to write a custom cast for it. I was wondering how is it possible to do so?
Let's assume the class is as follows:
class Person {
private int age;
private float weight;
// getters and setters and etc
}
I would like the int cast to return the member age of an object, and the float cast to return the weight of an object.
For instance:
public class Main {
public static void main(String[] args) {
// create an object
Person P = new Person();
P.setAge(21);
P.setWeight(88.0);
// case 1: casting object to an existing data type
int personAge = (int) P; // would return the age
float personWeight = (float) P; // would return the weight
// case 2: casting an existing data type to an object
Person P2 = (Person) personAge; // this would create an instance of the object whose age is assigned and weight is not assigned
}
}
I was wondering if it is possible to do the opposite. In particular, casting int to Person would return an instance of Person that its age is assigned and similarly for float.
I know this question may not have an answer. But because I did not find any useful results in my search, I decided to ask it.
P.S. I understand that for a String, the toString method would take care of case 1.
You can't overload the cast operator. Java doesn't support it and probably never will.
To convert a single value to an instance of the desired class, we use static factory methods.
public static Person fromAge(int age) {
return new Person(age);
}
They often return a partially constructed object. In the snippet above, a newly constructed person has only age set: other fields will have their default values.
To do the opposite, we use getters.
public int getAge() {
return age;
}
However, since toString is already there, it makes sense to add other data types as well.
toInt makes no sense when it's applied to me (as an instance of the Person class). It could be my height, my weight, my age, a number of times I went to a bathroom today, etc. I can't represent myself by one int number, neither can a large majority of classes.
On the other hand, toString can do this job pretty well: I can give you (read return) a summary of my hobbies, my biometric information, even my picture. Or I can leave it to the default implementation, which still would satisfactorily represent an object.
You wouldn't use a cast for this just write methods in your Person class to get those values.
public int getAge()
{
return age;
}
etc.
So I've only done this once and I'm unsure whether the approach I did is the appropriate way.
But my approach was a method called typeConverter, which i would give an object as parameter, then you could take that parameter and look what object type it is and then create a new Person, with your value.
Although this approach could cause problems, when your class would have two integer fields. But I think you could find a solution for this, by giving it another parameter that defines, which field you'd want to convert it to.
I'm really sorry for my poor english, but I hope you get the principle.

What's the point of get and set methods [duplicate]

This question already has answers here:
Set and Get Methods in java?
(16 answers)
Closed 8 years ago.
In my CS class I am just learning about classes and OOP.
So when you create a class you initialize a certain number of private variable.
I know you make them private because if they were public they would be easily changeable and could lead to a lot of bugs.
So we use get and set methods to change the variable. But that once again makes the variables very easy to change right? So whats the point of making them private in the first place?
Some benefits of using getters and setters (known as encapsulation or data-hiding):
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
As the above comment states, getters and setters encapsulate (i.e. hide) inner details of your class. Thus other classes that interact with yours, do not need to know about the implementation details.
For example, in the simple case you describe, instance variables are exposed via getters and setters. But what if you wanted to change your class so that you no longer used instance variables, but rather you persisted the values to disk. You could make this change to your class without affecting the users of your class.
Keep in mind also that getters and setters need not always be provided. If you do not want your class to provide a way to set or read these properties, then don't. Simply make them private.
get is used to obtain a value for an attribute and set is used to put a value to an attribute
ex:
private int variable;
public int getVariable(){
return variable;
}
public void setVariable(int aux){
variable=aux;
}
In general, is used to encapsulate an attribute.
reference:
Set and Get Methods in java?
Encapsulation or data hiding gives u more control on what values can be set to a field. Here is an example if you don't want a class attribute to have a negative value:
class WithoutGetterSetter {
public int age;
}
class WithGetterSetter {
private int age;
public setAge(int age) {
if(age < 0)
// don't set the value
else
this.age = age;
}
}
public class testEncapslation {
public static void main(String args[]) {
WithoutGetterSetter withoutGetterSetter = new WithoutGetterSetter();
withoutGetterSetter.age = -5;
WithGetterSetter withGetterSetter = new WithGetterSetter();
withGetterSetter.setAge(-5);
}
}
Get and Set methods are preferable to "public" variables because they insulate the users of a class from internal changes.
Supposing you have a variable "StockQty" and you made it public because that seemed like the easiest thing to do.
Later on you get a user requirement to track the history of stock over time. You now need to implement a SetStockQty() method so you can save the old quantity somewhere before setting the new quantity.
Now all the users of your class have to change there code, re-document and re-test.
If you had SetStockQty() method to begin with only you would need to change and test your code.
The second reason is you can have Getters without Setters effectivly making the variable "read only".
Traditionally, they are justified in terms of encapsulation. By providing moderated access to read and write the fields of a class, we supposedly reduce coupling.
In simpler language: by controlling the ways in which other classes can read and change our data, we reduce the ways in which our class's data can change. This means that the connections between classes are reduced, which reduces complexity.
However, the same logic says that getters and setters should generally be avoided unless there's an actual need for them, and there very seldom is such a need. For the most part, a class should "tend to its own knitting" - if there's a calculation to be done on this class's data, it should do it. If a value should be changed, it should do the changing.
For example, consider an object in space. It has a location specified as (x,y,z). We could possibly allow other classes to just set those arbitrarily - this would be horrible, obviously, but it's not obvious that a setter for these would be any better. What you really want is a constructor to set an initial position, and then methods to influence that position - for example, to register an impact or an acceleration. Then you're doing OO programming.
One word, Encapsulation.setters also allow you to control how values are entered into your program. Many new programmers like myself are often confused by this concept. I strongly advice you read this SO question
Being objective: it's all about best pratices!!!
1) IF necessary, expose your attributes with get methods.
2) IF necessary, allow attribute modification (state modification) using set methods;
Have both public get and set methods without treatment is the same as have the attributes public.

How to use variables in Java? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
This question may seem dumb at first, but after having worked with different person, I see everyone seems to have their own, different knowledge about it, so here's my question.
So now I'm wondering what is the best way to do it, and why ("why" is more important for me):
I'm wondering about two methods to write Java code:
Do you always pass Object or can you pass primitive data type ?
Do you call variables using this.name, name or getName() inside your class instance ?
public class MyClass {
private String someStr;
private int someNumber;
private Integer someOtherNumber; // int, Integer ? which one to choose ?
public MyClass(String someStr, int someNumber, int someOtherNumber) { // int someNumber ? Integer someNumber ? why ?
this.someStr = someStr; // Here, it's clearly this.{name} = {name} because of the variable name conflict
this.someNumber = someNumber;
this.someOtherNumber = someOtherNumber;
}
public int someMethod(boolean first) { // Boolean ? boolean ?
if (first) {
return someNumber;
} else {
return this.someOtherNumber; // this.{name} ? just {name} or even this.get{name}() or get{name}() ? (supposing getters exists)
}
}
}
I hope someone will provide me with a great explanation about which to use in order for me to write better code.
Do you always pass Object or can you pass primitive data type ?
You can't pass an Object, only a reference to an Object. You can pass primitive data.
Do you call variables using this.name, name or getName() inside your class instance ?
I don't make it more complicated than I need to, unless it's conflicts with a local variable or my getName() does something special, but that is a matter of style.
Do you always pass Object or can you pass primitive data type ?
You can pass primitives or references to objects depending on your need.
Do you call variables using this.name, name or getName() inside your
class instance ?
this is used to refer to the current object. If there are conflicting variable names and you want to distinguish between the object variable and local variable then use this.
Also you seems to be confused about primitives and Wrapper classes. Wrapper classes provides utilities methods and are of use especially working with collections.
If you need to work with the primitive data types then you should use them, e.g., int, double, char, float, etc. The only exception is String which in Java is a special class that represents a char array and also holds instance methods.
The case with Integer vs int, is when you need to use Integer methods (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html). But if you only need a data type to hold your value then choose int.
Do you always pass Object or can you pass primitive data type ?
public int someMethod(boolean first) { // Boolean ? boolean ?
}
In the following example, you can pass boolean and Boolean with the same success. In Java this is called Autoboxing.
N.B. Be careful, because when passing an object it may be null!
Do you call variables using this.name, name or getName() inside your
class instance ?
Depends. If name is an class member variable, you can access it with name if there isn't any other variable in the current scope that has the same name. In this case you should use this.name to point exactly to the class member variable. getName() may be used, as well. It's just a matter of style.
I keep it simple. I'm using name, but if I have a local variable with the same name I must use this.name (my prefered solution) over getName().
getName() must be used if it do some logic like validation.
Do you always pass Object or can you pass primitive data type ?
It depends on your application and your needs. If you pass a reference to an object, you are able to use the methods of the related type which may be more secure and portable. Let say you are using the class Double. Double has many peer-reviewed and tested methods which may be helpful to you.If you prefer to use primitive type, double, you need to be careful in your manipulations like comparing, validating etc.
For performance issue, you may check a previous discussion below:
Why do people still use primitive types in Java?
Do you call variables using this.name, name or getName() inside your class instance ?
I prefer using this when I refer a class member because i think it will be helpful for others reading my code to understand that the variable is a class member.
Finally, whatever style you prefer, I think you should stick to it in your applications.
Do you call variables using this.name, name or getName() inside your class instance ?
It is mostly a matter of personal style and principle.
private int someOtherNumber; I almost always use int because it seems more natural to me --perhaps influenced by the C days. And, from performance and memory usage point of view using int is a better choice. As a rule of thumb, I don't use objects for primitives unless I have a good reason to.
return this.getSomeOtherNumber(); I prefer using getters/setters; since sometimes -not always- the getter method is not just a simple return statement, rather it encapsulates some logic. As a result, I don't directly access class attributes (like this.someAttr or someClass.somePublicAttr) unless it's a final attribute. Believe me, it's much safer.
Continuing 2: It may seem a bit strange but I, having a strong Lisp background, try to avoid using even getter/setter methods (class state) as much as possible and instead explicity pass the required parameters and use the methods' return values. Consider the following example:
public class C {
private int a;
private int b;
public int getA() { return a; }
public void setA(int a) { this.a = a; }
public int getB() { return a; }
public void setB(int b) { this.b = b; }
// Usual style
public void someMethod1(int x) {
mainLogic1(x);
}
private void mainLogic1(int x) {
b = a + x;
}
// My preferred style
public void someMethod2(int x) {
setB(mainLogic2(x, getA()));
}
private int mainLogic2(int x, int a) {
return x + a;
}
}
As you can see, someMethod1 and mainLogic1 both have side effects which are hard to detect when looking at the code. On the other hand mainLogic2 doesn't have a side effect at all and someMethod2 side effect is easier to spot by just looking. This may seem like overkill, but it has made my Java code more readable, more testable and easier to refactor as it consists of large number of small methods with no side effects.

Java getter vs this

This is a very generic scenario, where I am setting a variable using setter function and using the variable only locally.
class Main {
private String str;
public Main(String value)
setStr(value);
}
private String getStr() {
return str;
}
private void setStr(String str) {
this.str = str;
}
public void display() {
//METHOD1
System.out.println(getStr());
//METHOD2
System.out.println(this.str);
}
}
What would be the better practise to follow between the two METHOD1/2 in display function, basically what would be the better way of using "str" variable.
Does it even make sense to have private getter/setter functions?
Ivard
If the getter is private, and doesn nothing more than returning a private variable, it isn't needed, IMHO (i.e. I prefer the second method of accessing it).
But if the getter was public and not final, and could thus be redefined by a subclass, then you'd have to decide if you want to get the potentially overridden value returned by the getter, or if you want the value of the private field in the display method.
Here should be at least one comment with Yes.
By providing new abstraction barrier you can separate data accessors and data presentation. For example, lets look at complex number class. Which can be implemented as
class ComplexNumber {
private final double realPart;
private final double imaginaryPart;
ComplexNumber(double realPart, double imaginaryPart) {
this.realPart = realPart;
this.imaginaryPart = imaginaryPart;
}
public double getRealPart() {
return realPart;
}
public double getImaginaryPart() {
return imaginaryPart;
}
}
or in polar expressions form
class ComplexNumber {
private final double r;
private final double angle;
ComplexNumber(double r, double angle) {
this.r = r;
this.angle = angle;
}
public double getR() {
return r;
}
public double getAngle() {
return angle;
}
}
Presume that you should implement basic operation like +-/*. What presentation model should you choose? For addition and subtraction standard model preferable, but for multiplication and division polar form preferable. So you can create getters for both form. And implement add/_sub_ like you have standard model and div/_mult_ like with polar form. This operation wouldn't depend from your actual data presentation. For change presentation you should change getters. Thats all. In Java world it's called self encapsulation.
For simple cases you'd just use this.str. For more complex cases, you might want to inherit from such a class, and have getStr() be implemented in a subclass perhaps it would lazily get the string from a file/database. Then these methods would't be private though.
For trivial cases where you just assign and fetch a private member, not really. For more complex cases where you might need to do additional logic, it'd make sense to confine that logic to one place. As with 1., it would make sense if you want sub classes to override the methods as welll.
Unless you have a side effects in your public getter which you desire I would consider always using this for consistency unless inheritance is assumed.
It doesn't make sence at all to me to employ private accessors. A routine should typically only do one thing and preferably without side effects. Creating a private getter
without side effects only creates useless redundancy.
with side effects basically proves that either the method is doing too much or is poorly named
Using this might also make refactoring easier [1].
[1] Refactoring a private variable gives less impact than refactoring a method. If you later decide to change the contract, e.g., by no longer providing a getter routine you will get less to refactor. Besides, many editors highlight all occurences of a variable when pointing the cursor to it, which is lost when hiding its use in a sub-routine.
No, it's not useful to have private getter/setter methods. If they were public or otherwise overridible by subclasses though it would be a different story. Should a subclass override your getter/setter, it could change the way the display() method functions.

Is there any mistake in this Java code?

class Creature {
private int yearOfBirth=10;
public void setYearOfBirth(int year) {
yearOfBirth = year;
}
void setYearOfBirth(Creature other) {
yearOfBirth = other.yearOfBirth; // is this correct it compiles fine
}
int getYearOfBirth() {
return yearOfBirth;
}
public static void main(String args[])
{
Creature c = new Creature();
c.setYearOfBirth(89);
Creature d = new Creature();
c.setYearOfBirth(d);
System.out.println(c.yearOfBirth);
}
}
Is there any mistake in this code?
Is "other.yearOfBirth" wrong? My faculty says it is wrong but it works fine for me.
As written, it will work, as you discovered. I suspect that there's a fundamental misunderstanding at play, though.
My psychic powers tell me that your instructor expected code more like the following:
class Creature {
private int yearOfBirth=10;
public void setYearOfBirth(int year) {
yearOfBirth = year;
}
public void setYearOfBirth(Creature other) {
yearOfBirth = other.yearOfBirth;
}
public int getYearOfBirth() {
return yearOfBirth;
}
}
class Program {
public static void main(String args[]) {
Creature c = new Creature();
c.setYearOfBirth(89);
Creature d = new Creature();
c.setYearOfBirth(d);
System.out.println(c.yearOfBirth); // This will not compile
}
}
The misunderstanding is that you've only created one class-- your main application class. This effectively makes yearOfBirth a sort of hybrid global value that you can access from your main method. In more typical designs, Creature is a class that is completely independent of your main method. In that case, you must only access Creature through its public interface. You would not be able to access its private field directly.
(Note to any pedants out there: Yes, I know I'm simplifying.)
You have to ask your faculty to explain why they think it's wrong (its perhaps a question of style, or even a misunderstanding), so you can learn from it.
Ultimately this person is going to impact your grades. This is an excellent opportunity to have a positive interaction with them. The more involved your teachers are with teaching you personally, the better your opportunity for mastering your subject will be.
If on the other hand when you're told something is wrong you go away privately and ask the general internet community, there is a risk that you'll be told you're right and you'll end up a false sense of superiority over your teachers which will be very counterproductive.
i detect nothing wrong.
the code works, because an instance or class can access private members of other instances of the same class. this is by design.
No, there is no problem at all with it.
Look, it depends on the viewer opinion. But for a given context this code may be just perfect.
For some other context this may not be correct. So it depends of how is going to be used.
Accessing a private member directly from another instance, is correct ( not always desirable though, for instance when you're subclassing ) that's why it is private in first place. You are saying "Hey, this is mine and I know how to use it"
Using the default access modifier for the other two methods, says that your intention is they should not be used by other classes outside the package.
Probably the only thing I would add is to make the class final.
final class Creature
If you want to make it inheritable you probably have to review the get/set for the yearOfBirth attribute, but they way it is is perfect to me.
NOW The most important thing here, is that you understand what each part of your code does, and how it affects its behavior.
You should no code just by luck ( sorry I don't know what's the correct expression for this ) but you should know what you're doing each time you type something, and how do you intend to be used.
I see two "issues," though I hesitate to call them mistakes:
You're explicitly setting Creature c's age as 89, and then rewriting that age with the uninitialized default (!) of Creature d. If this is what you intend to do, then fine, but at the very least you're wasting a few cycles to set a value that you intend to throw out later.
You're possibly violating the JavaBeans naming conventions.
To explain the latter point: a lot of Java libraries and frameworks (notably JSP) rely on JavaBeans to treat the object as a component. I haven't dived deeply into the actual mechanisms used, but from what I've read it relies on Introspection of the JavaBeans class to infer properties and the types of those properties. By overloading your setter setYearOfBirth() to accept both an int and a Creature, you could throw off the Introspection. (See here for a decent introduction to JavaBeans.)
This is not a big deal -- its entirely possible that you won't use this class as a JavaBean, and if you do it's trivial to refactor it so it works. But your teachers would probably prefer something a little cleaner, like the following:
class Creature {
private int yearOfBirth=10;
public void setYearOfBirth(int year) {
yearOfBirth = year;
}
int getYearOfBirth() {
return yearOfBirth;
}
public static void main(String args[])
{
Creature c = new Creature();
c.setYearOfBirth(89);
Creature d = new Creature();
c.setYearOfBirth(d.getYearOfBirth());
System.out.println(c.getYearOfBirth());
}
}
Now all of your access to yearOfBirth comes via the public getter methods, which helps encapsulation, and will prevent the code from breaking if your main method moves to another class. (As Greg D correctly pointed out.)
Also, this has the added benefit of making the intent of your code clear, which becomes more and more important when you start writing code for others to maintain and modify.
It's wrong because you're accessing a private member (you declared private int yearOfBirth) of another object although the class type is the same. You should use the public getter you defined instead: yearOfBirth = other.getYearOfBirth()
yearofBirth is a private int. Therefore the call to other.yearOfBirth would presumably fail...

Categories