For my CS class I am required to use some premade code and use the interface in my spreadsheet. I have a few classes already, Program, SpreadSheet, PersistanceHelper and an interface Savable.
package persistence;
public interface Savable {
public String[] getSaveData();
public void loadFrom(String[] saveData);
}
package persistence;
import java.io.*;
import java.util.*;
public class PersistenceHelper {
public static void save(String filePath, Savable toSave) throws Exception {
String[] data = toSave.getSaveData();
PrintStream out = new PrintStream(new File(filePath));
try {
for (String datum : data) {
out.println(datum);
}
} finally {
out.close();
}
}
public static void load(String filePath, Savable toLoadTo) throws Exception {
ArrayList<String> data = new ArrayList<String>();
Scanner input = new Scanner(new File(filePath));
try {
while (input.hasNextLine()) {
data.add(input.nextLine());
}
} finally {
input.close();
}
String[] dataArray = new String[data.size()];
toLoadTo.loadFrom(data.toArray(dataArray));
}
}
//These are this class and interface I am not allowed to change and I am required to use the save and load methods in the PersistanceHelper and am struggling to create a variable of the Savable type.
An interface simply describes how a class behaves externally. To get an instance, it must know how to retrieve results from declared functions, specified by the implementation:
public class MySavable implements Savable {
public String[] getSaveData() {
// some code
return whatever;
}
public void loadFrom(String[] saveData) {
// some code
}
}
You can then do things like:
Savable s = new MySavable();
String[] strings = s.getSaveData();
s.loadFrom(strings);
Implement the savable interface class , by child class say savableImpl. And that object you use with this interface.
Isn't it whole point of having interface.
public class SavableImpl implements Savable{
public String[] getSaveData(){
// implementation goes here
}
public void loadFrom(String[] saveData){
// implementation here
}
}
Then you can go like this :-
Savable savable = new SavableImpl();
I am pretty sure, whoever designed existing class , meant same to be done .
Related
I am aware about the static keyword, but in short. My attempt is to create inner static class since it's related to outer class. The practical problem is I am confused how to access it. My reason use static class is that I just need one instance of it per application?
Please correct if you found any misconseption, and give real usage of the class / static class.
public class DbPredecessorTest {
List<Book> db;
Book book;
Integer numberOfBooks;
static BufferedReader reader;
static {
try {
reader = new BufferedReader(new FileReader(Main.fileLoc));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
static class Helper {
DbPredecessor dbPredecessor= new DbPredecessor();
Long getLines() {
return reader.lines().count();
}
}
My directionless attempt:
class SomeTest {
#Test
void ableToSave() throws IOException {
db.add(book);
boolean save = Helper.dbPredecessor.save(db);
assertEquals(true, save);
}
#Test
void save_should_increaseLine() throws IOException {
db.add(book);
// numberOfBooks= (int) Helper.get
boolean save = dbPredecessor.save(db);
assertEquals(numberOfBooks+1, reader.lines().count());
}
}
That's not the reason to use a static inner class. A static inner class is functionally an ordinary Java class, the only real reason you would have one is to indicate it's related to the outer class in some way or to make it private.
You could just use a normal static method here:
public class DbPredecessorTest {
static long getLines() {
return reader.lines().count();
}
}
and then use it like so:
long numberOfBooks = DbPredecessorTest.getLines();
I have a utility class OldRemote which has been deprecated now, but still it will be used for a while till the new class NewRemote is stable. And both the utility classes has the same method names and parameters, But the return type pojo classes are different. Even return type pojo structure is same, but naming is different.
In simple, both the function return types are pojo's with different field names.
Is there any generic way to handle this below usecase ?
I have created a service interface which has the generic method contract of both old and new class.
public interface RemoteService {
//contract [ return type is object to receive all/any Pojo classes ]
Object turnOnTV();
static Service GetRemoteservice(boolean isOldRemote){
if(isOldRemote){
return new OldRemote();
}
return new NewRemote();
}
}
OldRemote Class
public class OldRemote implements RemoteService{
#Override
public OldPojo turnOnTV() {
OldPojo oldPojo = new OldPojo();
System.out.println("OldPojo");
return oldPojo;
}
}
NewRemote Class
public class NewRemote implements Service{
#Override
public NewPojo turnOnTV() {
NewPojo newPojo = new NewPojo();
System.out.println("NewPojo");
return newPojo;
}
}
Demo usage of above implementation.
public class DemoTvRemote {
public static void main(String[] args) {
RemoteService remoteService1 = RemoteService.GetRemoteservice(true);
OldPojo oldRemote = (OldPojo) remoteService1.turnOnTV();
RemoteService remoteService2 = RemoteService.GetRemoteservice(false);
NewPojo shr = (NewPojo) Service2.test();
}
}
This above code works fine. But the problem is I don't want to type cast in all the places where turnOnTV() is used in my entire code base. Even If I have to do that, I will have to write a condition to switch between OldPojo and NewPojo where ever the turnOnTV() is invoked.
Is there any way to solve this problem ?
You could create a base class or interface they both extend/implement.
public abstract class RemoteServiceBase<E> {
public abstract E turnOnTv();
}
public class NewRemoteService extends RemoteServiceBase<NewRemotePojo >{
public NewRemotePojo turnOnTv() {
return new NewRemotePojo();
}
}
public class OldRemoteService extends RemoteServiceBase<OldRemotePojo >{
public OldRemotePojo turnOnTv() {
return new OldRemotePojo();
}
}
This would still only work if you know the service type. Otherwise you work with the common generic type as one would expect.
We can deal with this with the following approach :
1) We can create a dummy POJO class in a common location with having the reference of both OldPojo and NewPojo as data members
public class CommonPojo {
OldPojo oldPojo;
NewPojo newPojo;
public void setOldPojo(OldPojo oldPojo){
this.oldPojo=oldPojo;
}
public void setNewPojo(NewPojo newPojo){
this.newPojo=newPojo;
}
public OldPojo getOldPojo(){
return oldPojo;
}
public NewPojo getNewPojo(){
return newPojo;
}
}
2)We can write a Utility method as follow which can give an object of commonpojo :
public class CommonRemote {
public static CommonPojo turnOnTv(Boolean isOldRemote){
CommonPojo commonPojo = new CommonPojo
if(isOldRemote){
OldPojo oldPojo =new OldPojo();
commonPojo.setOldPojo(oldPojo);
}else{
NewPojo newPojo =new NewPojo();
commonPojo.setNewPojo (newPojo);
}
}
}
3) Use this method as turnOnTv() as Follows :
public class DemoTvRemote {
public static void main(String[] args) {
CommonPojo remote1 = CommonRemote.turnOnTv(true);
OldPojo oldRemote = remote1.getOldPojo();
CommonPojo remote2 = CommonRemote.turnOnTv(false);
NewPojo newRemote = remote2.getNewPojo();
}
}
with this approach with little changes in code We can achieve your requirement without any typecasting.
[EDIT: I've rewritten the code to further simplify it and focus on the issue at hand]
I'm working on this particular piece of code:
class SimpleFactory {
public SimpleFactory build() {return null}
}
class SimpleFactoryBuilder {
public Object build(final Class builderClazz) {
return new SimpleFactory() {
#Override
public SimpleFactory build() {
return new builderClazz.newInstance();
}
};
}
}
However, the builder in the return statement triggers the error "Cannot find symbol newInstance". It's as if builderClazz wasn't recognized as a class object.
How can I make it work?
EDIT: SOLUTION (thanks to dcharms!)
The code above is a partial simplification of the code I was dealing with. The code below is still simplified but includes all the components involved and includes the solution provided by dcharms.
package com.example.tests;
interface IProduct {};
interface ISimpleFactory {
public IProduct makeProduct();
}
class ProductImpl implements IProduct {
}
class SimpleFactoryBuilder {
public ISimpleFactory buildFactory(final Class productMakerClazz) {
return new ISimpleFactory() {
#Override
public IProduct makeProduct() {
try {
// the following line works: thanks dcharms!
return (IProduct) productMakerClazz.getConstructors()[0].newInstance();
// the following line -does not- work.
// return new productMakerClazz.newInstance();
}
catch (Exception e) {
// simplified error handling: getConstructors() and newInstance() can throw 5 types of exceptions!
return null;
}
}
};
}
}
public class Main {
public static void main(String[] args) {
SimpleFactoryBuilder sfb = new SimpleFactoryBuilder();
ISimpleFactory sf = sfb.buildFactory(ProductImpl.class);
IProduct product = sf.makeProduct();
}
}
You cannot instantiate a new object this way. builder is a Class object. Try instead the following:
return builder.getConstructors()[0].newInstance(anInput);
Note: this assumes you are using the first constructor. You may be able to use getConstructor() but I'm not sure how it would behave with the generic type.
I am used to use generics in typed collections, but I never actually used them to develop something.
I have several classes like this:
public class LogInfoWsClient extends GenericWsClient {
public void sendLogInfo(List<LogInfo> logInfoList) {
WebResource ws = super.getWebResource("/services/logInfo");
try {
String response = ws.accept(MediaType.TEXT_HTML).type(MediaType.APPLICATION_XML).put(String.class, new GenericEntity<List<LogInfo>>(logInfoList) {
});
}
}
Where the only thing changing between one and another is the service String ("/services/info"), and the type of the list (LogInfo in this case)
I have refactored a couple of methods to a GenericWsClient class, but my objective would be to have something I can use like this:
List<LogInfo> myList = database.getList();
SuperGenericClient<List<LogInfo>> superClient = new SuperGenericClient<List<LogInfo>>();
superClient.send(myList,"/services/logInfo");
But I cannot figure out how to do it, or even if its possible. Would it be possible?
Yes it is possible infact if you look at java.util.collection package for example you will find all classes to be parameterzid.
So your class will be something like this
public SuperGenericClient<E> {
public E getSomething() {
return E;
}
}
Then to use it you will have
SuperGenericClient<String> myGenericClient = new SuperGenericClient<String>();
String something = myGenericClient.getSomething();
Extending your example itself your code will look like this:
public class SuperGenericClient<E> extends GenericWsClient {
public void send(List<E> entityList, String service) {
WebResource ws = super.getWebResource(service);
try {
String response = ws.accept(MediaType.TEXT_HTML).type(MediaType.APPLICATION_XML).put(String.class, new GenericEntity<E>(entityList) {
});
}
}
}
public class GenericEntity<E> {
public GenericEntity(List<E> list){
}
}
You must read this for a very good understanding of Generics.
You could write your class like the one below - you can apply the same idea to GenericEntity.
public class SuperGenericClient<T> extends GenericWsClient {
public void send(List<T> list, String service) {
WebResource ws = super.getWebResource(service);
try {
String response = ws.accept(MediaType.TEXT_HTML).type(MediaType.APPLICATION_XML).put(String.class, new GenericEntity<T>(list) {
});
}
}
}
You can then call it like that:
List<LogInfo> myList = database.getList();
SuperGenericClient<LogInfo> superClient = new SuperGenericClient<LogInfo>();
superClient.send(myList,"/services/logInfo");
Declare your class like this:
public class LogThing<T> {
public void sendLogInfo(List<T> list) {
// do thing!
}
}
And when you use it, do so like this:
List<LogInfo> myList = db.getList();
LogThing<LogInfo> superClient = new LogThing<LogInfo>();
superClient.sendLogInfo(myList);
For school I need to learn Java and since I'm used to C++ (like Cocoa/Objective-C) based languages, I get really frustrated on Java.
I've made a super-class (that can also be used as a base-class):
public class CellView {
public CellViewHelper helper; // CellViewHelper is just an example
public CellView() {
this.helper = new CellViewHelper();
this.helper.someVariable = <anything>;
System.out.println("CellView_constructor");
}
public void draw() {
System.out.println("CellView_draw");
}
public void needsRedraw() {
this.draw();
}
}
public class ImageCellView extends CellView {
public Image someImage;
public ImageCellView() {
super();
this.someImage = new Image();
System.out.println("ImageCellView_constructor");
}
public void setSomeParam() {
this.needsRedraw(); // cannot be replaced by this.draw(); since it's some more complicated.
}
#Override public void draw() {
super.draw();
System.out.println("ImageCellView_draw");
}
}
Now, when I call it like this:
ImageCellView imageCellView = new ImageCellView();
imageCellView.setSomeParam();
I get this:
CellView_constructor
ImageCellView_constructor
CellView_draw
However, I want it to be:
CellView_constructor
ImageCellView_constructor
CellView_draw
ImageCellView_draw
How can I do this?
Thanks in advance,
Tim
EDIT:
I also implemented this method to CellView:
public void needsRedraw() {
this.draw();
}
And this to ImageCellView:
public void setSomeParam() {
this.needsRedraw(); // cannot be replaced by this.draw(); since it's some more complicated.
}
And I've been calling this:
ImageCellView imageCellView = new ImageCellView();
imageCellView.setSomeParam();
Does this causes the problem (when I call a function from the super it calls to the super only)? How can I solve this... (without having to redefine/override the needsRedraw()-method in every subclass?)
You should get proper output.
I tried you example just commented unrelated things:
import java.awt.Image;
public class CellView {
//public CellViewHelper helper; // CellViewHelper is just an example
public CellView() {
//this.helper = new CellViewHelper();
//this.helper.someVariable = <anything>;
System.out.println("CellView_constructor");
}
public void draw() {
System.out.println("CellView_draw");
}
public static void main(String[] args) {
ImageCellView imageCellView = new ImageCellView();
imageCellView.draw();
}
}
class ImageCellView extends CellView {
public Image someImage;
public ImageCellView() {
super();
//this.someImage = new Image();
System.out.println("ImageCellView_constructor");
}
#Override public void draw() {
super.draw();
System.out.println("ImageCellView_draw");
}
}
and I get following output:
CellView_constructor
ImageCellView_constructor
CellView_draw
ImageCellView_draw
This is exactly what you want, and this is what your code print's.
The short answer is "you can't."
Objects are constructed from the bottom up, calling base class initializers before subclass initializers and base class consrtuctors before subclass constructors.
EDIT:
The code you have looks good, based on your edit. I would go through the mundane tasks like ensuring that you have compiled your code after you've added you System.out.println calls to your subclass