+ 2
[Solved] Encapsulation and calling from main()
Hi, I'm trying to wrap my head around the practical applications of OOP in my coding. At the moment I'm focusing on a problem in having calling on a class separate from the class my main() is in. Hypothetical example, a class named MainClass which holds main() as its sole method. The actual program is in the class BodyClass holding a set of private static methods of different types. The only thing main() does is call a function from BodyClass and pass a value of type String to it. No return is expected.
15 odpowiedzi
+ 2
I suspect that I'm not able to call on the method in the other class without some sort of accessor. Is that correct, or are there better ways of accessing the functions of my program in the other class and still keep things encapsulated?
+ 2
im not exactly sure what you are asking, but encapsulation has to deal with hiding information from outside sources. for example making instance variables private is encapsulating those variables. then you use accessor methods and mutator methods to control what someone can do with that variable
+ 2
When I get home I'll try to exemplify what I'm asking with some code fragments.
+ 2
Let's say I broke up some code I submitted into separate classes. So, in DecoderRing.java I have:
import java.io.*;
import java.lang.*;
public class DecoderRing {
public static void main(String[] args) {
String ring = "abcdefghijklmnopqrstuvwxyz1234567890";
//Run until the user terminates with a ^C.
setKey(ring);
} // end main
}
In MovingParts.java I have:
public class MovingParts {
.
static Scanner scan = new Scanner(System.in);
private static void setKey(String str) {
String decision = "";
char firstLetter, secondLetter;
int index1, temp;
...
}
....
}
So, in class DecoderRing I would have to define an accessor method of some sort to be able to pass my String variable as an argument to setKey() and run the program?
+ 2
you have to call the method like this:
MovingParts.setKey (ring);
+ 2
setKey(), yes. Corrected my above post.
So I have to call setKey() as a member of the MovingParts class explicitly then? That's the rationale behind that?
+ 2
yeah you have to give some kind of reference as to where the method is located. otherwise it would think the method is part of the DecoderRing class, and it would think its missing it.
since setKey is static, you have to call it by MovingParts.setKey ()
static methods are called:
ClassName.staticMethodName ()
if you remove the static keyword, you would need to create an object so that you can call the method for
ex:
MovingParts movingObject = new MovingParts ();
movingObject.setKey (ring);
+ 2
a better way is to put it into a contructor for MovingParts
so do String ring = "...........";
MovingParts movingStr = new MovingParts (ring);
and inside MovingParts, the constructor would look like this
public class MovingParts {
private String str;
static Scanner scan = new Scanner ();
public MovingParts (String ring) {
str = ring;
}
..............
}
+ 1
Alright, now that I have played around with this, got it working and understand a bit better I have a follow-up question: In terms of encapsulation, is it better to keep the string I'm passing in main() strictly inside the MovingParts class rather than pass the string to MovingParts' methods from main(), or is that not really important?
+ 1
I think the decision to pass the string from main() in the DecoderRing class through the setter interface to the MovingParts class, or to embed the string in MovingParts will have design consequences later.
Current setup.
public class DecoderRing {
public static void main(String[] args) {
String ring = "abcdefghijklmnopqrstuvwxyz1234567890";
MovingParts movingStr = new MovingParts();
movingStr.setString(ring);
}
}
public class MovingParts {
static Scanner scan = new Scanner;
public void setString(String str) {
this.askKey(str);
}
private static void askKey(String str) {
. . .
+ 1
Ah yes, a constructor. I'll try that. Thank you.
+ 1
Okay, so now I have:
public class DecoderRing {
public static void main(String[] args) {
String ring = "abcdefghijklmnopqrstuvwxyz1234567890";
MovingParts movingStr = new MovingParts(ring);
movingStr.setString(ring);
}
}
public class MovingParts {
static Scanner scan = new Scanner(System.in);
private String str;
// Constructor
public MovingParts(String str) {
this.str = str;
}
// Setter
public void setString(String str) {
this.askKey(str);
}
. . .
I can't seem to get rid of movingStr.setString(ring) in main() and I can't get rid of the setter either as I seem to need it even if I have the constructor. Is this the recommended way of doing this then? I get the feeling that I'm overcomplicating something, but I don't know what the reasons are that it should be this way to make a good judgement here.
+ 1
inside main (), instead of calling setString, since it is already set in the constructor, you can do movingStr.askKey ();
and just change the askKey accordingly
+ 1
I think that there must be something that you know that I don't, because I did what I thought you suggested and this is what I keep getting.
DecoderRing.java:55: error: askKey(String) has private access in MovingParts
movingStr.askKey(ring);
^
1 error
Code fragments:
public class DecoderRing {
public static void main(String[] args) {
String ring = "abcdefghijklmnopqrstuvwxyz1234567890";
MovingParts movingStr = new MovingParts(ring);
movingStr.askKey(ring);
}
}
public class MovingParts {
static Scanner scan = new Scanner(System.in);
private String str;
// Constructor
public MovingParts(String str) {
this.str = str;
askKey(str);
}
// Setter
/* public void setString(String str) {
this.askKey(str);
} */
private static void askKey(String str) {
. . .
In main() I've removed the argument from askKey() and from the function in MovingParts and it complains about missing arguments. I've ran the constructor without calling on askKey(), called on askKey() without arguments and with arguments and it either gives the error above or the error above plus more errors.
I'm pretty tired right now so I think I'll sleep on it. It's probably something obvious.
+ 1
@Edward I think I figured it out. <s>A setter is required that is called from the constructor.</s> The ways I was doing it were either wrong or had just enough correct code to override my erroneous code. Thanks for your help, I had to struggle to wrap my head around these concepts and I think I understand them better now.
Here's the current working code.
https://code.sololearn.com/c02Uo32HF04F
Using constructors with get/setters.
http://stackoverflow.com/questions/17942580/java-setter-getter-and-constructor
Addendum: my self-guided education continues and I learn that I still have new understanding where I thought I had things figured out already.