[ACCEPTED]-Is it OK to have an 'empty' class that extends another class?-java
In my opinion, it's best if Foo
and Bar
subclass 11 off a common ancestor class (maybe AbstractFoo
), which 10 has all the functionality. What difference 9 in behaviour should exist between Foo
and Bar
? Code 8 that difference as an abstract method in 7 AbstractFoo
, not by using a if
statement in your code.
Example: Rather 6 than this:
if (foo instanceof Bar) {
// Do Bar-specific things
}
Do this instead:
class Bar extends AbstractFoo {
public void specialOp() {
// Do Bar-specific things
}
}
// ...
foo.specialOp();
The benefit of 5 this approach is that if you need a third 4 class, that's much like Foo
but has just a 3 little bit of difference, you don't have 2 to go through all your code and add edit 1 all the if
statements. :-)
It all depends on meaning of the Foo and Bar classes. What they represent, and what's their purpose. Please clarify.
I can imagine situations when each of your 2 solutions and proposed solutions is the 1 right one.
If there is any likelihood that Foo
and Bar
could 18 someday diverge in implementation, then 17 your question is answered - use inheritance 16 in whatever way seems best.
But if you're 15 absolutely sure that they'll never diverge, then 14 clearly you're looking at something that 13 should be represented by a single class, such 12 as ThingThatIsEitherFooOrBar
.
And with that class made, rather than 11 giving it a boolean property like isFoo
, it would 10 be much better to take another look at why 9 you need to differentiate Foo from Bar. What 8 is it about Foos that makes you handle them 7 differently than Bars? Figure that out, and 6 make a property that specifies the information 5 that differs. Are Foos bigger? Then make 4 a property for size (even if it's an enum 3 with values "Foo-sized" and "Bar-sized").
That's 2 about as much as one can say without specific 1 examples of what Foo and Bar might be.
Foo and Bar inherit from FooBarImplementation
I'd make a class FooBarImplementation that 23 would implement the common features of Foo 22 and Bar. Foo and Bar would derive from it. But 21 in your code, never ever use the type FooBarImplementation. My 20 Java days are somewhat behind me, but I 19 guess there must be some kind of way to 18 hide FooBarImplementation from the user 17 code (making it protected, or package visible 16 only, depending on your project organization. This 15 way, no user code will mix Foo for a Bar 14 (and vice versa)?
class FooBarImplementation
{
public void doSomething() { /* etc. */ }
/* etc. */
}
class Foo inherits FooBarImplementation { /* etc. */ }
class Bar inherits FooBarImplementation { /* etc. */ }
Foo and Bar composed with FooBarImplementation
Another possibility would 13 be to make Foo and Bar forward each of their 12 methods to an internal class (again, FooBarImplementation). This 11 way, there's no way the user code could 10 be Foo and Bar.
class FooBarImplementation
{
public void doSomething() { /* etc. */ }
/* etc. */
}
class Foo
{
private FooBarImplementation fooBarImplementation = new FooBarImplementation() ;
public void doSomething() { this.fooBarImplementation.doSomething() ; }
/* etc. */
}
class Bar
{
private FooBarImplementation fooBarImplementation = new FooBarImplementation() ;
public void doSomething() { this.fooBarImplementation.doSomething() ; }
/* etc. */
}
Do NOT make Foo inherits from Bar (or vice versa)
Shoudl Foo inherits from 9 Barn, Foo would be a Bar, as far as the 8 language is concerned. Don't do it, you'll 7 lose the difference between the objects, and 6 this is what you don't want.
Do not use boolean, and whataver type field
This is the 5 worst idea you could come accross. Bjarne 4 Stroustrup warned against this kind of antipattern 3 for C++, and C++ is not all about OOP. So 2 I guess this pattern is even more "anti" for 1 Java... :-)
Definitely use a boolean property. It's 3 the simplest solution, unless you foresee 2 the Bar class needing to change it's interface 1 later (e.g. override it's methods).
Inheritance is best.
With a boolean property, the 5 class must know about the existence of two 4 different types of objects, and this isn't 3 easily extensible to more than two. Moreover, this 2 approach doesn't let you overload functions.
Composition 1 makes you write wrappers for all functions.
your data was not clear enough, but based 6 on what I think you need, I am puzzled why 5 you don't simply go with a 4th option:
Class MainStuff;
Class TypeA;
Class TypeB;
No 4 either make TypeA and B inherit from MainStuff, or 3 make MainStuff a data member of TypeA and 2 TypeB. This depends on the meaning of what 1 these 3 classes are.
As others said, it depends, but if you have 33 common functionality between Foo and Bar 32 and the difference in functionality can 31 be expressed as parameters, then I vote 30 for subclasses. This was basically what 29 we were doing in the end of a practical 28 software course.
We should implement a sudoku-game, and 27 in the end, we had an "AbstractPlayfield", which 26 was able to apply an arbitrary set of rules 25 to an arbitrary playfield. This AbstractPlayfield 24 was subclassed by the individual variants 23 we were supposed to implement. Those subclasses 22 set parameters (mostly the rules and the 21 shape of the board) for the abstract playfield 20 and everything worked like a charm. We even 19 ended up with more inheritance in those 18 subclasses, because several of the variants 17 contained the rules "Numbers must be unique 16 in a row" and "Numbers must be unique in 15 a column".
Using that, we were able to finish 14 the work that was estimated for about 2 13 month in about 3 days :) (And they annoyed 12 us with "Test those tiny attribute-setting 11 classes, because you might have bugs in 10 there! Test them! Test them! We dont care 9 that all important logic is tested!".)
On 8 the other hand, if the class Bar has no 7 special different functionality from Bar, I 6 do not see the point of adding it - at least 5 from the data you give me. It might make 4 sense if you wanted to do some operations 3 based on types and dispatch on type, but 2 I cannot read that from Foo and Bar. In 1 this case, I'd not create Bar, due to YAGNI.
If there is no behavioral difference between 8 Foo and Bar, then the class name "Foo" is 7 not abstract enough. Identify the common 6 abstraction between Foo and Bar and rename 5 the class accordingly. Then provide a member 4 field in the class to identify instances 3 as "Foo", "Bar", etc. Use an enum if you 2 wish to limit possible values to "Foo" and 1 "Bar".
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.