If I have the following class, Foo, where Bar is also a class:
public class Foo {
private Bar baz;
public Foo() {
}
}
Am I right in thinking that if I initialise baz where it is declared I will have an aggregate relationship between Foo and Bar and if I initialise baz in Foo's constructor I will have a composite relationship? Like this:
Aggregate (I think this is probably incorrect?):
public class Foo {
private Bar baz = new Bar();
public Foo() {
}
}
Composite:
public class Foo {
public Foo() {
baz = new Bar();
}
}
I'm a little new to Java, and seeing as everything is a class, I'm having difficulty visualising how (in particular) the aggregate relationship works unless I make baz static. If I create baz somewhere else and pass it in to the constructor of Foo, then won't baz just be a composite of some other class? Bit confuzzled.
Try reading more about the dependency injection. It's what you describe in your last sentence. Its a pattern that removes hard-coded dependencies as in both of your examples, but this job is delegated to a higher-level authority.
You would get something like:
public class Foo {
private Bar baz;
public Foo(Bar baz) {
this.baz= baz;
}
}
The actual instance of baz can be changed in both compile and runtime.
The actual composition means that class Bar has no meaning (or value) without the class Foo, and it cannot exist without the Foo, - Bar "is a part of" Foo. An example would be: an IMEI number is a part of the phone.
The aggregation tells that Foo only owns the Bar, - Bar "has" Foo. An example would be: a battery is a part of the phone. Other devices that are not phones could also have batteries.
These two concepts don't have much to do with the way you code it.
Composition
final class Car{
private final Engine engine;
Car(EngineSpecs specs) {
engine = new Engine(specs);
}
void move() {
engine.work();
}
}
Aggregation
final class Car {
private Engine engine;
void setEngine(Engine engine) {
this.engine = engine;
}
void move() {
if (engine != null)
engine.work();
}
}
Related
The automapper I'm using, AutoMatter, allows inheritance, e.g.
#AutoMatter
public interface BaseClass {
Foo foo();
Bar bar();
}
#AutoMatter
public interface DerivedClass extends BaseClass {
Baz baz();
}
but its generated builders are not polymorphic, i.e. they are
#Generated("io.norberg.automatter.processor.AutoMatterProcessor")
public final class DerivedClassBuilder {
private Foo foo;
private Bar bar;
private Baz baz;
public DerivedClassBuilder() {}
private DerivedClassBuilder(DerivedClass v) {
this.foo = v.foo();
this.bar = v.bar();
this.baz = v.baz();
}
private DerivedClassBuilder(DerivedClassBuilder v) {
this.foo = v.foo;
this.bar = v.bar;
this.baz = v.baz;
}
// (getters and setters for the builder)
public DerivedClass build() {
// ...
}
public DerivedClassBuilder from(DerivedClass v) {
return new DerivedClassBuilder(v);
}
public DerivedClassBuilder from(DerivedClassBuilder v) {
return new DerivedClassBuilder(v);
}
// a few more things like hash(), equals(), etc.
}
The thing I need but isn't there is
public DerivedClassBuilder from(BaseClass v) {
// ...
}
This means, for example, if I have many common fields in the base class, but several different derived classes, I have to build all the common fields manually at some point, e.g.
DerivedClassBuilder builder = new DerivedClassBuilder();
builder.foo(foo);
builder.bar(bar);
builder.baz(baz);
instead of being able to do
DerivedClassBuilder builder = new DerivedClassBuilder(baseClassBuilder);
builder.baz(baz);
...which somewhat destroys the purpose of inheritance in the first place.
If I'm constrained to using this library, is there a pattern that can help me genericize this bit?
I've played around with adding a static helper method in the base interface, using generics to try to represent any derived class, but I seem to get stuck due to type erasure. And there is nothing like derivedClass.BuilderType to help me even if I try to use a copy-intersect library like Dozer.
Admittedly I'm new to Java, so I think either I'm missing something obvious, or it's simply impossible to do what I want to do, given builders that have no relation whatsoever to one another.
At work I came across the following design in a java project:
Consider interfaces Foo, Bar, and Baz as follows:
interface Bar { public int a(); }
interface Baz { public int b(); }
interface Foo extends Bar, Baz { public int c(); }
Now, consider class FooImpl:
public class FooImpl implements Foo {
private Bar bar;
private Baz baz;
public int a() {
return bar.a();
}
public int b() {
return baz.b();
}
public int c() {
return 0;
}
}
What are the use cases for this kind of class hierarchy? It seems to me that this introduces a lot of boilerplate and does not add much in terms of abstraction, other than breaking up what could be a large file into smaller files.
It allows things like this:
Foo foo = new FooImpl();
useBar(foo);
public void useBar(Bar bar) {
bar.a();
}
Whether this is useful depends on the real context. Your example code with classes and methods with meaningless names does not support a rational judgement.
The other thing to note is your FooImpl is actually implemented as some kind of wrapper for Bar and Baz instances. That's not (strictly speaking) an interface design issue.
I think it's a workaround for multiple inheritance (which is not allowed in Java). You're not showing implementations for Bar and Baz, but let's suppose they exist:
public class BarImpl implements Bar {
#Override
public int a() {
return 1;
}
}
public class BazImpl implements Baz {
#Override
public int b() {
return 2;
}
}
You neither have told us how Bar and Baz attributes are instantiated and set to FooImpl, because, if executed as stated in your question, you'll get a NullPointerException both in FooImpl.a() and FooImpl.b(). Again, let's imagine how this could be achieved:
public class FooImpl implements Foo {
private Bar bar; // better if final
private Baz baz; // better if final
// Constructor to properly initialize bar and baz
public FooImpl(Bar bar, Baz baz) {
this.bar = bar;
this.baz = baz;
}
#Override
public int a() {
return bar.a();
}
#Override
public int b() {
return baz.b();
}
#Override
public int c() {
return 0;
}
}
Wiring everything up:
Bar bar = new BarImpl();
Baz baz = new BazImpl();
Foo foo = new FooImpl(bar, baz);
int one = foo.bar(); // 1
int two = foo.baz(); // 2
In a way, FooImpl is "inheriting" from both BarImpl and BazImpl, though this is achieved by means of delegation.
To do this is really just redirecting fooimpl using its propertie's(bar and baz) "a" method and "b" method
This is a simplified example of something I'm currently designing.
public class ExampleManager {
private Foo foo;
private ArrayList<Example> examples;
...
public ExampleManager() {
this.foo = new Foo();
this.examples = new ArrayList<Example>();
}
public void add(Example e) {
examples.add(e);
}
public void doSomethingWithExamples() {
for (int i = 0; i < examples.size(); i++) {
examples.get(i).doSomething();
}
}
...
}
public abstract class Example {
private Foo foo;
public Example(Foo foo) {
this.foo = foo;
}
...
}
In order to use the library, I have to extend the Example class and add examples to the ExampleManager, which should be the only class that modifies the Example objects.
So I have this Example1 class:
public class Example1 extends Example {
public Example1(Foo foo) {
super(foo);
}
...
}
and I currently initialize the manager like this:
ExampleManager manager = new ExampleManager();
Example1 example1 = new Example1(manager.getFoo());
manager.add(example1);
My Example needs the Foo object, but I'm wondering if I could get rid of the Foo argument in the Example1 constructor, so if someone uses the library, doesn't have to call manager.getFoo() in order to create an Example.
I'm thinking about the following solution, which will hide the Foo initialization, so the person who makes use of the library just have to implement the initialize(Foo) method, and the Foo would be initialized automatically when adding the example to the ExampleManager)
In ExampleManager: change the add(Example) method for:
public void add(Example e) {
e.initialize(foo);
examples.add(e);
}
In Example, initialize(Foo foo); would be an abstract method, so in Example1 I would have something like this:
#Override
public void initialize(Foo foo) {
this.foo = foo;
}
Is there any better way to do this?
It seems to me that you have some issues with your OO model in the first place if you need to hand objects around like you describe. - Or maybe your sample code does not reveal the real point of things.
Especially
ExampleManager [...] should be the only class that modifies the Foo objects
and
Example needs the Foo object
look somewhat 'special'.
Can you elaborate what the interactions are between the ExampleManager and the Foo instance, and between the Example and the Foo instance?
Ok, with regard to your comment, I propose the observer pattern, much like your initialize() approach:
public abstract class Example {
protected Foo callbackHandler;
public void setCallbackHandler( Foo handler ) {
this.callbackHandler = handler;
}
protected void doCallback( SomeType event ) {
if ( this.callbackHandler != null ) {
this.callbackHandler.doYourThing( event );
}
}
}
and have ExampleManager register itself or its Foo instance as the callback handler when an object is added to it. Non-abstract subclasses will then only need to call doCallback(...) whenever they want to communicate something and won't have to deal with any setup stuff for the callback.
I was looking to implement an interface on a package-private java class, but I am having some difficulty achieving this. Below is an example.
class Foo
{
String something(String str)
{
return ""str+"!";
}
}
public interface Bar
{
String something(String str);
}
What is the best approach here? My end goal is to implement the Bar interface on the Foo class. I am hoping to be able to cast Foo as Bar: (Bar)Foo
The Bar interface and the Foo class are in separate packages. Is there a way to do this?
Please advise.
You can't. The point of having the package level access it to precisely avoid seeing that class outside. What you can do however ( granted Foo is not final ) something like this:
C:\>type *.java
//Foo.java
package foo;
class Foo {
String something( String s ) {
return s + "!";
}
}
//Bar.java
package bar;
public interface Bar {
public String something( String s );
}
//Baz.java
package foo;
import bar.Bar;
public class Baz extends Foo implements Bar {
// make sure you're overriding
#Override
public String something ( String s ) {
return super.something( s );
}
}
//Use it: Main.java
package bar;
import foo.Baz;
class Main {
public static void main( String ... args ) {
Bar bar = new Baz();
System.out.println( bar.something("like this?"));
}
}
C:\>java bar.Main
like this?!
Da da!
The trick is to define the child in the same package as the parent so you can create a public version of it.
I hope this helps.
When you doesn't have control on a class but you want to make it look like an API that you have, then you Adapt it to fit your needs. Hint: Adapter Pattern
Foo needs to implement Bar
protected class Foo implements Bar
Also, I think Foo.something needs to be public in order to implement Bar.something
Side Note: While it was probably just as an example,
return ""str+"!";
should be:
return str + "!";
If Foo is package private, and you don't have access to the source, just the classfiles and/or the jar containing Foo.class, there's not much to do -- something that is package private is invisible to classes in the default package (where there is no package specified) and other packages.
You'll need to use inheritance or composition if you don't have access to the source code of Foo.
// By logically including your code in the package containing Foo,
// you can now access it. If Foo belongs to the default package, sorry.
// This also doesn't work if the package is sealed.
package where.foo.resides;
public interface Bar {
String something(String s);
}
// Inheritance
public class FooBar extends Foo implements Bar {
public String something(String s) {
return super.something(s);
}
}
// Composition
public class ComposedFooBar implements Bar {
private final Foo delegate;
public ComposedFooBar(Foo delegate) {
this.delegate = delegate;
}
public String something(String s) {
return delegate.something(s);
}
}
You can try using bytecode injection with BCEL or ASM and setting the interface at runtime. It's tricky, though.
There might also be a way to change interaces with reflection, but I doubt it.
Private is there for a reason.
Given a class "Bar" that extends class "Foo" which implements interface "DeeDum"
public interface DeeDum {
public String getDee();
public String getDum();
}
public class Foo implements DeeDum {
public String dee = "D";
public String dum;
public String getDee() { return dee; }
public String getDum() { return dum; }
}
public class Bar extends Foo {
public String dee = "DEE";
public String dum = "DUM";
}
Why doesn't this work?
public static Bar mybar = new Bar();
Assert.assertEquals("DEE", mybar.getDee());
Assert.assertEquals("DUM", mybar.getDum());
I get "D" and null instead. In other words, Bar doesn't inherit accessors from Foo, and can't override properties. Somehow calling mybar.getDum() calls a static instance of class Foo and returns the static properties from the parent class. Even if the properties are overridden in the child class! Does that mean that you can't inherit any methods or properties?
I can't wrap my head around it. Why can't Java inherit accessors (and why did they choose such an odd alternative?)
Or am I just doing something wrong?
Actually, I'm seeing something weird and undeterministic still. If you have another class 'Bar' that extends Foo and sets the inherited accessors in an initialization block
While you can set the parent property in the above block, it doesn’t actually create a copy for the child class.
It seems to be a non-deterministic initialization for multiple classes.
So if you have Bar and Baz which both extend foo and have an initialization block, it seems like both inherit the value set by Bar.
public class Bar extends Foo {
{
dee = "dee";
dum = "dum";
}
}
public class Baz extends Foo {
{
dee = "DEE";
dum = "DUM";
}
}
public static Bar bar = new Bar();
public static Baz baz = new Baz();
System.out.println("mybaz: " + mybaz.getDee() + mybaz.getDum()); // DEEDUM
System.out.println("mybar: " + mybar.getDee() + mybar.getDum()); // DEEDUM
but if they're instantiated in a different order, I get:
public static Baz baz = new Baz();
public static Bar bar = new Bar();
System.out.println("mybaz: " + mybaz.getDee() + mybaz.getDum()); // deedum
System.out.println("mybar: " + mybar.getDee() + mybar.getDum()); // deedum
And it comes out still differently if a default is set in the base class Foo.
I think I understand now that the initialization block in Bar and Baz is actually setting Foo::dee and Foo::dum, but why the difference in declaration? Seems "undefined" to me.
The problem is that your duplicate declaration of the members dee and dum of Foo in Bar hides those of Foo. Bar has its own members; those of Foo will never be used by Bar. What you mean is something like
public class Bar extends Foo {
{
dee = "DEE";
dum = "DUM";
}
}
You are hiding the inherited variables with ones defined in the subclass.
public class Bar extends Foo {
public Bar() {
dee = "DEE";
dum = "DUM";
}
}
should work better.
When you call mybar.getDee(), you're calling the method defined in the Foo base class. (That method was inherited by Bar. Otherwise, you wouldn't have been allowed to call it on a Bar instance variable in the first place.) That method returns the value of the dee field, but it's the dee field defined in the Foo class — the class where the method itself was defined. The compiler resolved the reference to the field at the time the method was compiled, in the Foo class.
Some other answers have used the word override to define what you did by declaring a field named dee in Bar, but that's not what happened. You can't override a field because fields aren't virtual. Perhaps you thought they were, though. If there were such a thing as a "virtual field," I too might expect getDee() to return the run-time class's version of the field (the one in Bar) instead of the one that was in scope at the time the method was compiled (Foo's). But that's simply not the way Java (or C#, or C++, or Delphi, or any other language I know of) works. What language are you accustomed to where this would have worked?
Accessor methods themselves (e.g. getDee()) are inherited, but instance variables are not.
If instance variables could be overridden in subclasses (like you're trying to do here), it would cause many more problems than it would fix.
Accessors aren't the problem, it's the fields. The accessors are referring to Foo.this.dee, not to Bar.this.dee which are separate.
As for your second "question"...
Actually, I'm seeing something weird and undeterministic still...
...
"...System.out.println(baz.getDee()); // 'DEE' but would expect 'dee'"
It would be useful if you run the program before posting the question to see actual results.
This is what I get. It is "dee" as you expected.
You could see it for your self by creating the files, compiling them and the run them as shown below:
C:\oreyes\samples\java\dee>type DeeDum.java Foo.java Bar.java Baz.java Test.java
DeeDum.java
public interface DeeDum {
public String getDee();
public String getDum();
}
Foo.java
public class Foo implements DeeDum {
public String dee = "D";
public String dum;
public String getDee() { return dee; }
public String getDum() { return dum; }
}
Bar.java
public class Bar extends Foo {
{
dee = "DEE";
dum = "DUM";
}
}
Baz.java
public class Baz extends Foo {
{
dee = "dee";
dum = "dum";
}
}
Test.java
class Test {
public static Bar bar = new Bar();
public static Baz baz = new Baz();
public static void main( String [] args ) {
System.out.println(bar.getDee()); // 'DEE'
System.out.println(baz.getDee()); // 'DEE' but would expect 'dee'
}
}
C:\oreyes\samples\java\dee>javac *.java
C:\oreyes\samples\java\dee>java Test
DEE
dee
C:\oreyes\samples\java\dee>
PEBKAC?