Consider the following code for a read only interface pattern in Java:
package package2;
public interface AccountsReadOnly {
public String getValue();
}
package package1;
import package2.AccountsReadOnly;
class Accounts implements AccountsReadOnly {
private String name;
public Accounts() {
name = "unknown";
}
public String getValue() {
return name;
}
public void setValue(String name) {
this.name = name;
}
}
package package1;
public class Manager {
Accounts allAccess;
public Manager() {}
}
package package2;
public class Employee {
public AccountsReadOnly accountReadOnly;
public Employee() {}
}
public class Demo {
public static void main(String[] args) {
Manager m = new Manager();
Employee e = new Employee();
Accounts a = new Accounts();
m.allAccess = a;
m.allAccess.setValue("Andrew");
System.out.println(m.allAccess.getValue());
e.accountReadOnly = a;
System.out.println(e.accountReadOnly.getValue());
}
}
I can't understand this line as this is the first time for me to see this format:
m.allAccess.setValue("Andrew");
Is it possible to use instead of this line since they have the same reference?
m.setValue("Andrew");
Is m.allAccess a reference of the object?
Is it possible to use instead of this line since they have the same reference?
no, m.setValue("Andrew"); does not work, because the Manager-class has no function setValue
Is m.allAccess a reference of the object?
yes, allAccess references the Account-object which is set in this line: m.allAccess = a;
The getValue and setValue methods should really be named getNameand setName, because that what they do. setValueshould return a value, e.g. the account's balance.
Also nameis not read-only if you have a setter for it.
Related
I would like have one method declare two Strings and assign them values. Then have another method to read those values.
I have this structure:
public class ABC extends CDE implements EFG {
public void firstMethod(valueOne, valueTwo) {
class TestClass {
public String testValue = valueOne;
public String anotherValue = valueTwo;
}
}
public void readMethod() {
// HERE I WANT TO READ testValue AND ASSIGN IT A NEW VALUE
}
}
How can I do that?
And is there a better way?
Are you sure you need a class?
May be a simple field declaration will be enough:
public class ABC extends CDE implements EFG {
public String testValue;
public String anotherValue;
public void firstMethod(String valueOne, String valueTwo) {
// do whatever you wish with testValue and anotherValue
}
public void readMethod() {
// here you have access to both variables
}
}
Make the local class global and set/read values via instance:
public class ABC extends CDE implements EFG {
class TestClass {
public String testValue = valueOne;
public String anotherValue = valueTwo;
}
private testClassInstance = new TestClass()
public void firstMethod(valueOne, valueTwo) {
testClassInstance.testValue = valueOne
testClassInstance.anotherValue = valueTwo
}
public void readMethod() {
System.out.println(testClassInstance.valueOne)
System.out.println(testClassInstance.valueTwo)
}
}
All you want to do is to create a POJO that holds testValue and anotherValue and declare the class outside of your component class, e.g.:
class ExampleBean {
private String testValue;
private String anotherValue;
//getters and setters
}
Once done, you can hold the reference of that class into your component class and access the value, e.g.:
public class ABC extends CDE implements EFG {
ExampleBean exampleBean = new ExampleBEan();
public void firstMethod(valueOne, valueTwo) {
exampleBean.setValueOne(valueOne);
exampleBean.setAnotherValue(valueTwo);
}
public void readMethod() {
String value = exampleBean.getValueOne();
}
}
Maybe this will fit your criteria?
What you are currently asking for is impossible due to the scope of the inner class.
You could also initialize this private class instance in your constructor.
public class Sample {
class TestClass {
public String testValue;
public String anotherValue;
}
private TestClass localTest = new TestClass();
public void firstMethod(valueOne, valueTwo) {
localTest.testValue = valueOne;
localTest.anotherValue = valueTwo;
}
public void readMethod() {
localTest.testValue = "test1";
localTest.anotherValue = "anotherValue";
System.out.println(localTest.testValue);
}
}
You are declaring a class withing a method , which is not right
You need to understand what a class and a method really mean ( Google Java OOP ) :
1- You should create a class and declare the variables you want
2- make constructors for the default values
3- make setters to set (assign) these values
4- make getters to read those values
I'm a bit confused with subclasses.
Here's my code:
public class MedHistory {
private String grafts;
private String allergies;
private String diseases;
private String surgeries;
private String medicalTreatment;
//Constructors (#2)
public MedHistory(String allergies, String diseases, String grafts,
String treatments, String surgeries) {
this.allergies=allergies;
this.diseases=diseases;
this.grafts=grafts;
this.medicalTreatment=treatments;
this.surgeries=surgeries;
}
public MedHistory() {
this.allergies="";
this.diseases="";
this.grafts="";
this.medicalTreatment="";
this.surgeries="";
}
//Getters
public String getGrafts() {
return grafts;
}
public String getAllergies() {
return allergies;
}
public String getDiseases() {
return diseases;
}
public String getSurgeries() {
return surgeries;
}
public String getMedicalTreatment() {
return medicalTreatment;
}
//Setters
public void setGrafts(String grafts) {
this.grafts = grafts;
}
public void setAllergies(String allergies) {
this.allergies = allergies;
}
public void setDiseases(String diseases) {
this.diseases = diseases;
}
public void setSurgeries(String surgeries) {
this.surgeries = surgeries;
}
public void setMedicalTreatment(String medicalTreatment) {
this.medicalTreatment = medicalTreatment;
}
public class FemMedHistory extends MedHistory {
private List<Birth> births = new ArrayList<Birth>();
//Constructors (#2)
public FemMedHistory(String allergies, String diseases, String grafts,String treatments, String surgeries, List<Birth> birthlist) {
super(allergies,allergies,grafts,treatments,surgeries);
this.births=birthlist;
}
public FemMedHistory() {
super();
this.births=null;
}
//Getter
public List<Birth> getBirths() {
return this.births;
}
//Setter
public void setBirths(List<Birth> list) {
this.births=list;
}
}
}
When I try to create an new FemMedHistory object like this:
List<Birth> list = new ArrayList<Birth>();
list.add(new Birth(new GregorianCalendar(2011,4,10),"kaisariki",4));
FemMedHistory female = new FemMedHistory("allergia2","astheneia2","emvolia2","farmekeutiki agwgi2", "xeirourgeia2", list);
I get the error:
No enclosing instance of type MedHistory is accessible. Must qualify
the allocation with an enclosing instance of type MedHistory (e.g.
x.new A() where x is an instance of MedHistory).
So, which is the right way to use a subclass?
When you declare a nested class it only available through the Outer class.
To access it outside, you will need to either make the FemMedHistory class static.
public static class FemMedHistory extends MedHistory {...}
access it through the MedHistory class
MedHistory.FemMedHistory myMedHistory = ...
or declare it in it's own Java file.
You have declared your subclass as an inner class, which means that you can't create an instance of it without first creating an instance of the containing class.
The most common way to solve this is to declare it as a separate class, which would get rid of your error.
Long story short: cut all the FemMedHistory code and paste it into FemMedHistory.java. The way it is now you have involved Java concepts which you have not yet mastered. Also, that class really does belong in a separate file.
I have a primary class as below:
public class classB{
public classC getObject(String getstring){
return new classC(getstring);
}
}
The classC has a contructor:
public class classC{
String string;
public classC(String s){
this.string = s;
}
public methodC(int i){
<using the `string` variable here>
}
}
Now I've a classA which will be using the object created in classB(which is of course, an instance of classC).
public classA{
int a = 0.5;
<Get the object that was created in classB>.methodC(a);
}
This is needed as a variable is created on some actions from the user and stored in classB and this would be further used in classC's methods. Creating a new object will render my variable in classB set to null which isn't intended.
How can I achieve this?
Assume the Brand is a lightweight objects and Run is heavyweight then creating a field with the container for the lightweight objects and hiding it is a good idea.
But the Brand needs access the container it belongs to it could be done with the mapping but we are simply inject the Run to the Brand so it's better implement the Runable or annotate it with JSR330. And accessing the container through the Run in the normal way.
class MainClass {
public static void main(String[] args) {
Run r = new Run();
}
}
class Run {
private Container con1 = new Container();
public Run() {
Brand cola = new Brand("Coca Cola");
Brand pepsi = new Brand("Pepsi");
// Creates the container object "con1" and adds brands to container.
add(cola);
add(pepsi);
}
public void add(Brand b){
con1.addToList(b);
b.setRun(this);
}
public Container getContainer() {
return con1;
}
}
class Brand {
// In this class I have a method which needs to accsess the con1 object
// containing all the brands and I need to access the method
private String name;
private Run run;
public Brand(String name){
this.name = name;
}
public void brandMethod() {
if(getRun().getContainer().methodExample()) { // Error here. Can't find "con1".**
System.out.println("Method example returned true.");
}
}
public Run getRun() {
return run;
}
public void setRun(Run run) {
this.run = run;
}
}
class Container {
// This class is a container-list containing all brands brands
private ArrayList<Object> list = new ArrayList<Object>();
public boolean methodExample(){
return false;
}
public void addToList(Object o) {
list.add(o);
}
}
If you want to get the object created in classB a static field should do the job
public class classB {
public static objectCReference;
public classC getObject(String getstring){
objectCReference = new classC(getstring);
return objectCReference;
}
}
Then you can access the reference in A
public classA {
int a = 0.5;
if (classB.objectCReference != null) { // Make sure to null check
classB.objectCReference.methodC(a);
}
}
Also please follow the language conventions and start your class names with capital letters.
I have been give a jar file to use that has a static inner class inside of another static inner class:
package externalJarFile;
public class Job
{
public static class GlobalVars
{
private List<Job.GlobalVars.Variable> variables;
public List<Job.GlobalVars.Variable> getVariable()
{
if (this.variables == null) {
this.variables = new ArrayList<Job.GlobalVars.Variable>();
}
return this.variables;
}
public static class Variable
{
String name;
String value;
public String getName() { return name; }
public void setName( String name ) { this.name = name; }
public String getValue() { return value; }
public void setValue( String value) { this.value= value; }
}
}
}
The problem I'm having is that I need to populate the "Job.GlobalVars" list, but I can't figure out how to reference the "Variables" type. Whenever I add:
import externalJarFile.Job.GlobalVars.Variable;
I get a compilation error that the type "externalJarFile.Job.GlobalVars.Variable" cannot be referenced. How can I create a new "Variable" instance to add to the "GlobalVars.getVariable()" list?
Here's a snippet that I tried (but didn't work):
Job.GlobalVars vars = new Job.GlobalVars();
Job.GlobalVars.Variable v = new Job.GlobalVars.Variable();
[Edited for clarity]
[UPDATE]
Ok, this is kinda weird. If I take the code from the original project and directly import it into mine, I'm able to reference the inner-inner-class. However, when I reference it when it's packaged inside of a jar file, it fails. MTK...
You forgot a space:
Job.GlobalVars vars = new Job.GlobalVars();
^
This works fine for me:
Job.GlobalVars.Variable var = new Job.GlobalVars.Variable();
var.setName("MByD");
Class job:
package mypackage;
import java.util.ArrayList;
import java.util.List;
public class Job {
public static class GlobalVars
{
private List<Variable> variables;
public List<Variable> getVariable()
{
if (this.variables == null) {
this.variables = new ArrayList<Variable>();
}
return this.variables;
}
public static class Variable
{
String name;
String value;
public String getName() { return name; }
public void setName( String name ) { this.name = name; }
public String getValue() { return value; }
public void setValue( String value) { this.value= value; }
}
}
}
Other class using GlobalVars and Variable. Import works very good.
package mypackage;
import mypackage.Job.GlobalVars;
import mypackage.Job.GlobalVars.Variable;
public class RunIt {
public static void main(String[] args) {
GlobalVars vars = new GlobalVars();
Variable v = new Variable();
}
}
No need to import anything. You should be able to just refer to your inner class by its name, "Variable", from the "Job" class:
private List<Variable> variables;
public List<Variable> getVariable()
They way you had stated above is correct. You should check to ensure that the jar file is in your classpath as that would definitely cause the import to fail and subsequently all future declarations.
import mypackage.Job.GlobalVars.Variable;
...
Variable v = new Variable();
I have two classes
public class PrepaidPackage {
private String name;
private String serviceClassID;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceClassID() {
return serviceClassID;
}
public void setServiceClassID(String serviceClassID) {
this.serviceClassID = serviceClassID;
}
}
other class is
public class PostpaidPackage {
private String name;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I want to create a factory class which on base of package type create relevant class. But if you look at above clasess they dont have same type of methods and variables. So please guide how create interface or abstract class for above class?
Now factory will return class name Package. Would i able to call methods which are not present in other class.
Updates
Please suggest if i break my package into two classes like
public abstract class MyPackage {
public abstract PackageSpec getSpec();
public abstract PackagePrepaidDetails getDetail();
}
Now common attributes will be in PackageSpec and prepaid stuff in packageDetails.
Its kind of abstract factory pattern.
public class PrepaidPackage extends MyPackage{
PackageSpec spec;
public Spec getSpec() {
spec = new PackageSpec();
spec.setTranferable(true)
spec.setName("abc");
return spec;
}
public PackagePrepaidDetails getDetails() {
details = new PackagePrepaidDetails ();
details.setServiceClassID(123)
return details;
}
}
public class PostpaidPackage extends MyPackage{
PackageSpec spec;
public Spec getSpec() {
spec = new PackageSpec();
spec.setTranferable(true)
spec.setName("abc");
return spec;
}
}
I recomment you to have an interface if you don't have already. You do not neccessarily need it, but it is a good practice if they are so similar:
public interface Package {
public boolean isTranferable();
public void setTranferable(boolean isTranferable);
public String getName();
public void setName(String name);
}
Then in your calling code, you have a Package from your factory and:
Package p = myFactory.nextPackage(); // or something
if (p instanceof PrepaidPackage) {
PrepaidPackage prepaid = (PrefpaidPackage)p;
// and do the thing you want
} else if (p instanceof PostpaidPackage) {
PostpaidPackage postpaid = (PostpaidPackage)p;
// amd do the other things
}
Thing you are recommended to llok into is the instanceof operator and type casting.
A quick fix, not an ideal one is to have an interface that represents all the methods in the Prepaid class and leave them unimplemented in the Postpaid. That will solve the problem in the short term. I would suggest that you have a relook of the classes and the usages to avoid unimplemented methods in the code.
Well for an abstract super class you have to group everything common to both :
public abstract class MyPackage { // not sure you can call a class just "Package"
private String name;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
then both inherits from it (the first adds serviceClassID and the second nothing)
your factory function will return a MyPackage (or AbstractPackage, whatever), but to access the specific function you'll have to cast after an instanceof test.
Two possible design choices you can make:
Have the prepaid package extend
postpaid package and your factory
then returns objects of type
postpaid package, the code which
calls the factory is then
responsible for inspecting the type.
Have a package interface which
defines all of the methods and have
postpaid package define the methods
to throw an
UnsupportedOperationException (ala
the way collections defines some
operations as optional.) or return
some kind of sentinel value (i.e. null)
For either of the above you could add another method getType() which returns an enum of the various package types you wish to implement, and this could then be used in the code that accesses the factory objects to determine which methods are available.