I sometimes write classes which can be converted to- and from- something else, and I'm used to writing it as a non-static convert-to method and a static convert-from method, for example:
class A {
B toB() {...}
static A fromB(B b) {...}
}
or
class B {
void save(File f) {...}
static B load(File f) {...}
}
I used to think it's a good and simple approach, but lately the static-ness of the conversion-from method has been annoying me, for instance if I want to define an interface for types that can be converted to- and from- B:
interface ConvertableToAndFromB {
B toB();
// ?
}
So, is there an elegant way of doing that without having the conversion-from as static, other than migrating to Smalltalk?
EDIT
To clarify, I realize I can add a non-static method in the interface, e.g.:
interface ConvertableToAndFromB {
B toB();
void fromB(B b);
}
or, if I want to allow immutable types (thanks Stripling):
interface ConvertableToAndFromB<T implements ConvertibleToAndFromB<T>> {
B toB();
T fromB(B b);
}
But that will require me to create a new A before I can even invoke this, as in:
A a = new A();
a.fromB(b);
or (for immutable):
A a = new A();
a = a.fromB(b);
which is what I'm trying to avoid (but will do with no other solution). I just hope there's a nicer way.
You should be able to make your interface recursively generic. I believe the syntax is like this:
interface ConvertibleToAndFromB<T implements ConvertibleToAndFromB<T>>{
B toB();
T fromB(B b);
}
class A implements ConvertibleToAndFromB<A> {
B toB() {...}
A fromB(B b);
}
Making things more strongly typed like this has obvious advantages. However, it does mean that you have to be somewhat aware of the actual type that you want when you call fromB. There are advantages and disadvantages to this approach.
As a side note, making A responsible for generating objects of type A or B violates the Single Responsibility Principle, and I would generally prefer to have a separate Converter class or interface to perform these actions.
Converter<A, B> converter = converterFactory.get<A, B>(A.class, B.class);
B b = converter.from(a);
Often, a fromB method would be implemented as a copy constructor. E.g.
public class A
{
public A(B b)
{
this.someValue = b.someOtherVariable;
}
}
Unfortunately this does not help you create an interface to abstract said functionality. Normally, a separate factory could be used, and this factory implement an interface, but this would still not allow you to get around being able to implement the method in your object in a non-static way while avoiding unnecessary instantiation.
In your scenario, I'll do it this way:
interface ConvertableToA {
A toA() {...}
}
interface ConvertableFromA {
Object fromA(A a) {...}
}
class MyConvertableClass implements ConvertableToA, ConvertableFromA {
...
}
creating a utility helper class might be better because if you think about it, conversation has nothing to do with the object/instance.
for example, when you convert an array to list, you don't do arr.asList(), rather, you use Arrays.asList(arr)
Related
(With static and dynamic I mean the distinction whether code is susceptible to change)
I have a bit of a weird problem I'm currently stuck on. I'm writing an application which involves some complex interactions between components in which it becomes hard to keep track of the code flow. To simplify this, I'm trying to structure the code by creating 'layers', where each layer has increased functionality compared to the layer above it. Each layer is contained in a package. I'm having the following problem:
Consider the following 2 classes and their subclasses with increased functionality:
Class A:
package layer;
class A {
B b;
A() {
b = new B();
}
void foo() {
b.foo();
}
/* More A-class methods here */
}
Class B:
package layer;
class B {
void foo() {
// Do something
}
/* More B-class methods here */
}
Subclass A:
package sublayer;
class ASub extends A {
ASub() {
super.b = new BSub(); // This needs a cast to compile
}
}
Subclass B:
package sublayer;
class BSub extends B {
#Override
void foo() {
// Do something with more functionality
}
}
In the end I just want to instantiate and modify classes ASub and BSub, being able to use all methods of superclasses A and B without actually needing to modify code in classes A and B itself.
If I call new ASub().foo(), I want the overridden foo() of BSub to execute instead of that of B. Ofcourse I can add a variable BSub bsub in ASub and override A's foo() method to call bsub.foo(), but this doesnt avoid the creation of the object b in the constructor of A, which seems sloppy coding. Any thoughts on this? Any comments are welcome.
Your question is a bit controversial. Object creation and dependency injection is the subject of a lot of discussion and a core focus of various frameworks and design patterns.
But here is, I hope, one simple answer to your question, which isn't a general "what's the best way to create objects in Java?"
In the code below, I move the responsibility of instantiating B to a method (instantiateB()) which is called from the A (superclass) constructor. So, when you want to subclass A, you override that method instead of overriding the constructor.
package com.matt.tester;
public class SE {
static class A {
B b;
A() {
instantiateB();
}
void instantiateB () {
this.b = new B();
}
void foo() {
b.foo();
}
/* More A-class methods here */
}
static class B {
void foo() {
System.out.println("Hellow from B.foo()!");
}
/* More B-class methods here */
}
static class ASub extends A {
#Override
void instantiateB() {
this.b = new BSub();
}
}
static class BSub extends B {
#Override
void foo() {
System.out.println("Hellow from BSub.foo()!");
}
}
public static void main(String[] args) {
A a = new ASub();
a.foo();
}
}
Using inheritance to promote reusability is a really really bad idea. The inheritance should be always driven by the nature of the objects that you are trying to describe. You need to learn yourself to work with terms and abstractions to ask yourself "What is the nature of what I am trying to describe". My suggestion is to learn a book on Domain Driven Design for example or Code Complete. Also think about polymorphism and design patterns.
I have a very basic doubt about Java Interfaces and inheritance.
Suppose I have two classes A and B and one interface C with following definitions
interface C{
public void check();
}
class A implements C{
public void check(){
System.out.println("A");
}
}
class B extends A implements C{
// Is the following method overriding the method from class A or implementing the method from C?
public void check(){
System.out.println("B");
}
}
I am confused that whether it is over-riding or implementation of check() method in class B?
It does both, they are not mutually exclusive. The purpose of an interface is to define a method signature that should be available inside the implementing class.
You should annotate the method with #Override though, it's just good form because it makes clear that it comes from a baseclass and it'll guard you against accidental typos.
As #Jeroen Vannevel and #EJP have mentioned above it's both overriding and implementing.
In order to understand this I think you need to see it in the context of compile/run time.
You have the following possible scenarios:
C c = new B();
c.check();
At compile-time you see C#check() (you can use your IDE to get you where c.check() points to) at runtime you see the overridden B#check()
A a = new B();
a.check();
At compile-time you see A#check() (you can use your IDE to get you where c.check() points to) at runtime you see the overridden B#check()
B b = new B();
b.check();
At compile-time you see B#check() (you can use your IDE to get you where c.check() points to) at runtime you see the overridden B#check()
If alternatively you are passing the method call directly in a method:
someMethod(new B().check())
then this equates the last of the above scenarios
It is both over-riding and implementing.
In your example:
class B extends A implements C{
// Is the following method overriding the method from class A or implementing the method from C?
public void check(){
System.out.println("B");
}
}
You are defining the check method in interface C as:
public void check(){
System.out.println("B");
You are allowed to do this as interfaces don't contain the definition of the method in the interface when they are created and can thus be used over and over again for things which are similar enough to use the same method with a few tweaks.
I am trying to pass a Class to a method. The Class changes as the program runs, so I'd like to reuse the same method through out my program instead of calling the same functions throughout my resetWords() method.
Here is where I am stuck:
private void getWords(Class c) {
singles = c.getSingleSyllables();
doubles = c.getDoubleSyllables();
triples = c.getTripleSyllables();
quadruples = c.getQuadrupleSyllables();
quintuples = c.getQuintupleSyllables();
}
private void resetWords() {
if (generated.equals("SOMETHING")) {
Something c = new Something();
getWords(c);
}
else if (generated.equals("ANOTHER")) {
Another c = new Another();
getWords(c);
}
}
I think what you are looking for is an interface. You should declare an interface like this:
public interface Passable
{
public List<String> getSingleSyllables();
public List<String> getDoubleSyllables();
// ...
}
Then, let Something and Another implement them:
public class Something implements Passable
{
// method declarations
}
Now, change your method to this:
private void getWords (Passable c) {
singles = c.getSingleSyllables();
doubles = c.getDoubleSyllables();
triples = c.getTripleSyllables();
quadruples = c.getQuadrupleSyllables();
quintuples = c.getQuintupleSyllables();
}
A little vague what you're asking but perhaps create an Interface that defines all of the getXSyllables() methods. Have your classes (Something and Another) implement that Interface. Finally, define getWords as private void getWords(YourInterface c).
You're confusing classes, and objects.
What you're passing to getWords() is an object. In the first case, it's an object of type Something. In the second case, it's an object of type Another.
The only way for such code to work is to define a common base class or interface for Something and Another (let's call it HavingSyllabes), containing the 5 methods used in getWords(): getSingleSyllables(), getDoubleSyllabes(), etc. And the signature of getWords() should be
private void getWords(HavingSyllabes c)
If the classes always implement getSingleSyllables(), getDoubleSyllables(), etc.. then you should consider inheriting from an abstract class, or implementing an interface.
Then...
private void getWords(YourInterface / YourAbstractClass foo) {
...
}
Your question does not provide enough detail to answer clearly.
Depending upon your design / end-goals, there are three concepts you should take a look at and understand:
Interfaces
Abstract Classes
Reflection
An Interface will define the methods that classes that implement the interface must provide. Each class that implements the interface must provide the code for the method.
An Abstract Class will provide a single implementation of the behavior that you are looking for.
Reflection is an advanced concept. I would recommend you stay away from it at this time - but you should be aware of it.
Given your example code, you may want to use an Abstract Class. Designed properly, you can increase flexibility/reuse by defining an interface, implementing that interface with an Abstract Class and then extending that Abstract Class as needed. Every class that extends the Abstract will pick up the default implementation you provided in the Abstract class definition; the Interface will make it easy for you to extend in the future.
Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO
This isn't exactly the definition of implicit type conversion, but I'm curious how many standards I'm breaking with this one...
I'm creating an abstract class in Java that basically casts its variables depending on a string passed into the constructor.
For example:
public abstract class MyClass {
Object that;
public MyClass(String input){
if("test1".equals(input){
that = new Test1();
}
else{
that = new Test();
}
}
public void doSomething(){
if(that instanceof Test1){
//specific test1 method or variable
} else if(that instanceof Test2)}
//specific test2 method or variable
} else {
//something horrible happened
}
}
}
You see what I'm getting at? Now the problem I run into is that my compiler wants me to explicitly cast that into Test1 or Test2 in the doSomething method - which I understand, as the compiler won't assume that it's a certain object type even though the if statements pretty much guarantee the type.
I guess what I'm getting at is, is this a valid solution?
I have other classes that all basically do the same thing but use two different libraries depending on a simple difference and figure this class can help me easily track and make changes to all of those other objects.
You are right. This is a horrible way to achieve polymorphism in design. Have you considered using a factory? A strategy object? It sounds like what you are trying to achieve can be implemented in a more loosely-coupled way using a combination of these patterns (and perhaps others).
For the polymorphism of doSomething, for example:
interface Thing {
public void doThing();
}
class Test1 implements Thing {
public void doThing() {
// specific Test1 behavior
}
}
class Test2 implements Thing {
public void doThing() {
// specific Test2 behavior
}
}
class MyClass {
Thing _thing;
public void doSomething() {
_thing.doThing(); // a proper polymorphism will take care of the dispatch,
// effectively eliminating usage of `instanceof`
}
}
Of course, you need to unify the behaviors of Test1 and Test2 (and other concrete Thing classes, present and planned) under a set of common interface(s).
PS: This design is commonly known as Strategy Pattern.
I would create a separate class file. So you would have something like this:
1. You abstract "MyClass"
->within "MyClass" define an abstract method call doSomething...this will force the specific implementation of the method to it's subclasses.
2. Test1 would be the implementation of MyClass which would contain the implementation of the doSomething method
3. Create a utility class that does the check "instanceOf" that check should not be in the constructor it belongs in another class.
So in the end you would have 3 class files an Abstract Class, Implementation of the Abstract and a Class that does the "instanceOf" check. I know this sounds like a lot but it's the proper way to design, for what I think you are attempting to do. You should pick up a design patterns book, I think it would help you a lot with questions like these.
The Open-Closed principle would be better satisfied by moving the object creation outside of this class.
Consider changing the constructor to accept an object that implements an interface.
public MyClass {
public MyClass( ITest tester ) { m_tester = tester; }
public void doSomething(){ m_tester.doTest(); }
}
This makes it possible to change the behavior of the class (open to extension) without modifying its code (closed to modification).
The better way to do this is to create an interface which will specify a set of methods that can be guaranteed to be called on the object.
Here's an example:
public interface TestInterface
{
void doTest();
}
Now you can write your classes to implement this interface. This means that you need to provide a full definition for all methods in the interface, in this case doTest().
public class Test implements TestInterface
{
public void doTest()
{
// do Test-specific stuff
}
}
public class Test1 implements TestInterface
{
public void doTest()
{
// do Test1-specific stuff
}
}
Looks really boring and pointless, right? Lots of extra work, I hear you say.
The true value comes in the calling code...
public abstract class MyObject
{
Test that;
// [...]
public void doSomething()
{
that.doTest();
}
}
No if statements, no instanceof, no ugly blocks, nothing. That's all moved to the class definitions, in the common interface method(s) (again, here that is doTest()).