Specializing method arguments in subclasses in Java - java

Consider the following situation:
public abstract class AnimalFeed{
}
public class FishFeed extends AnimalFeed{
}
public class BirdFeed extends AnimalFeed{
}
public abstract class Animal{
public void eat(AnimalFeed somethingToEat)
}
Now I would like to define a class "Bird" extending "Animal" being sure that when the bird eats, it eats only BirdFeed.
One solution would be to specify a sort of contract, in which the caller of "eat" must pass an instance of the appropriate feed
public class Bird extends Animal{
#Override
public void eat(AnimalFeed somethingToEat){
BirdFeed somethingGoodForABird
if(somethingToEat.instanceOf(BirdFeed)){
somethingGoodForABird = (BirdFeed) somethingGoodForABird
}else{
//throws error, complaining the caller didn't feed the bird properly
}
}
}
Is it acceptable to delegate the responsibility of the parameter to the caller? How to force the caller to pass a specialization of the parameter? Are there alternative design solutions?

You'd need to add a type variable to the class:
public abstract class Animal<F extends AnimalFeed> {
public abstract void eat(F somethingToEat);
}
Then you can declare your subclasses as wanting a particular type of AnimalFeed:
public class Bird extends Animal<BirdFeed> {
public void eat(BirdFeed somethingToEat) {}
}
public class Fish extends Animal<FishFeed> {
public void eat(FishFeed somethingToEat) {}
}

What you are asking for doesn't make sense from an theoretical point of view.
Restricting a method parameter violates the Liskov Substitution Principle.
The idea there: any occurance (usage) of some base class object must be able to deal with some sub class object, too.
A more simple example: when your base interface goes:
void foo(Number n)
then you must not do
#Override
void foo(Integer i)
in a subclass. Because all of a sudden, a caller
someObject.foo(someNumber)
would run into ugly ugly problems when someObject is of that derived class; which only accepts Integers, but not Numbers.
In other words: good OO design is much more than just writting down A extends B. You have to follow such rules; or you end up with systems are already broken on a conceptual point!
And for the record: it is theoretically valid to widen method parameters (in general, but in Java); and it is also ok to restrict the return types of methods (because these changes can not break client code; and that even works in Java).
Long story short: the answer here is too change your design; for example by using Generics and dependent interfaces to somehow create a relationship between the Animal and the Feed class hierarchy.

Related

Hide non mutual methods in superclass facade

Is there a way we can hide the non mutual methods for types which are not qualified for the specific methods?
Lets say we have an abstract superclass with methods we don't want to expose to the objects themselves. We create a facade with the methods we want to allow for the objects. (We dont want to be able to set a cats age to 32 out of the blue.)
I end up in a scenario where i expose methods for a specific subclass that was actually meant for another subclass. (Even if we in the method can controll that the type is correct)
Scenario:
public abstract class Animal {
//setters and code we want to protect
}
public class Cat extends Animal{
private boolean giveBirth;
public void giveBirth(){giveBirth = true;}
//setters etc
}
public class Bird extends Animal{
private boolean layEgg;
public void layEgg(){layEgg = true;}
//setters etc
}
public class FacadeAnimal {
Animal animal;
public FacadeAnimal(Animal a){
animal = a;
}
public void layEgg(){
if(animal instanceof Bird){
((Bird) animal).layEgg();
}
}
public void giveBirth(){
if(animal instanceof Cat){
((Cat) animal).giveBirth();
}
}
}
So in this case we can control inside the method that the type needs to be Bird if we want to layEgg. But it would also be okay for us to let a Cat layEgg. Even though the logic is taken care of, it's still not very intuitional to give Cat the option to lay eggs.
I was thinking it's possible to create an "facade inheritance structure", where we for every subclass also create a facade for that specific subclass. But in the terms of extensibility, that means we will force future developers to not only create a subclass, but also an implementation of it's facade.
Is this the way to go or can we change the way we wrap this around?
Cheers!
EDIT: Maybe the animalscenario was not very clear.
It could in the same manner be two different cars, where one has turbo and one has not, if the "activateTurbo" method exists in the facade, i would be able to call the activateTurbo method on a car that does not actually have a turbo.
Method names such as giveBirth() and layEgg() are too specific - consider something more common such as:
public abstract class Animal {
public void reproduce();
}
Then each subclass can implement as needed. For examle:
public class Cat extends Animal {
public void reproduce() {
liveBirth();
}
private void liveBirth() {
// ...
}
}
and
public class Bird extends Animal {
public void reproduce() {
layEgg();
}
private void layEgg() {
// ...
}
}
This approach will likely lead to at least some duplicate code in the private methods. As #Lini said, combine with the strategy pattern. A little refactoring, and it changes from inheritance to composition.
I would unify giveBirth() and layEgg() into one single method in Animal, the subclass decides itself what to do.
You can also encapsulate this behavior into a new class something like NextGenerationStrategy with subclasses LayEggStrategy or GiveBirthStrategy.
The subclass of Animal (Bird or Cat) selects itself the strategy. So when you work with Animal you dont care it lays egg or gives birth.

How to use generics with multiple coupled objects?

So I'm having trouble wrapping my head around the proper design for this.
My application has two key objects that control state, that need to interact with one another: ItemList, ItemState. These each rely on a generic ITEM_TYPE so they can function in different contexts. They are also abstract to allow for ITEM_TYPE-dependent behavior.
Both pieces need to know the generic type, but moreover, since they talk to one another, they need to know the generic types of one another. (An ItemList< String > instance needs to know that its ItemState field is an ItemState< String > and vice versa).
My current solution works, but it seems awful. There has to be a better way. This is what I'm doing now:
public abstract class ItemState<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
public abstract class ItemList<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
Then an implementing class might look like:
class StringState extends ItemState<String, StringState, StringList> {
}
class StringList extends ItemList<String, StringState, StringList> {
}
Note that for ItemState, STATE_TYPE is a reference back to the implementing class, and likewise for ItemList/LIST_TYPE.
Really my problem would be solved if I just make ItemState an inner class of ItemList since there would be an implicit binding and they could share generic declarations, but both classes are so large and standalone, that I would prefer not to do this.
Any suggestions?
Edit: As a counter-example to a comment:
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList getItemList();
public void doSomething() {
// This should not compile because abstract super class has
// no idea what the generic type of getItemList() is
ITEM_TYPE item = this.getItemList.getItem();
}
}
Edit 2: I think the best solution I could think of was just to make ItemList/ItemState inherit one way or the other so they can function as the same class. I don't love this solution because it overrides separation of concerns, but it makes the generics a lot more manageable.
Sidenote: my actual applicaiton had this problem with 4 intertwined classes, I just used 2 for simplicity. In actuality the generics were so bad they were incomprehensible and hard to refactor (about 4 entire lines of just generic declarations for each class). I've now made these 4 classes into a vertical inheritance hierarchy
JM Yang's solution is pretty good
I think you may just reference to generic type ITEM_TYPE when declaring these 2 classes.
I'm able to compile below code with no errors.
public abstract class ItemList<ITEM_TYPE> {
public abstract ItemState<ITEM_TYPE> getState();
public abstract ITEM_TYPE getItem();
}
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList<ITEM_TYPE> getItemList();
public void doSomething() {
ITEM_TYPE item = getItemList().getItem();
System.out.println(item);
}
}
public class StringList extends ItemList<String> {
#Override
public StringState getState() {
return new StringState();
}
#Override
public String getItem() {
return "";
}
}
public class StringState extends ItemState<String> {
#Override
public StringList getItemList() {
return new StringList();
}
}

Java inheritance; passing a subclass to an abstract method of a superclass

Sorry for the title, couldn't come up with anything clearer.
I have the following structure:
public interface Vehicle {...}
public class Car implements Vehicle {...}
then:
public abstract class Fixer {
...
abstract void fix(Vehicle vehicle);
...
}
and would like to have:
public class CarFixer extends Fixer {
void fix(Car car) {...}
}
but this doesn't work. Eclipse says: The type CarFixer must implement the inherited abstract method Fixer.fix(Vehicle). Any idea how can I solve this?
You can use Generics to solve this:
public abstract class Fixer<T extends Vehicle> {
abstract void fix(T vehicle);
}
public class CarFixer extends Fixer<Car> {
void fix(Car car) {...}
}
The problem with your original version is that the fix method allows any type of vehicle, but your implementing class allows only cars. Consider this code:
Fixer fixer = new CarFixer();
fixer.fix(new Bike()); // <-- boom, `ClassCastException`, Bike is a vehicle but not a car
You've met the humble home of generics.
Generics provide kind of 'wildcard' type where a class or method can specify that 'we don't really care what type it is, we just need -a- type'.
Generics allow a super class to enforce a specific type in a child class instead of allowing any class that extends a certain class.
This means that you're ultimately enforcing a new highest allowed super-class as the parameter (i.e. Vehicle is no longer the most basic allowable type you can pass to fix(); it's now whatever the subclass says it is, so long as that arbitrary type extends Vehicle).
Common places for generics are container classes (i.e. List, Map, and Set) where the container doesn't really care about what type it tracks, but rather focuses on actually tracking and managing those instances.
Generics consist of one or more type placeholders (in Java, E and T are commonly used but the name doesn't really matter; they usually follow the normal type naming conventions) that are used in place of a specific class or super class.
In your code, you want subclasses to implement methods given their exact relevant types (i.e. a CarFixer would take Cars, a JetpackFixer would take Jetpacks) but you want to enforce that these types extend Vehicle.
In order to enforce this, you have to tell the Fixer class exactly what your subclass wants.
public abstract class Fixer <E extends Vehicle>
{
abstract void fix(E vehicle);
}
Your subclass then extends Fixer, filling in E with the type it wants.
public class CarFixer extends Fixer<Car>
{
#Override
void fix(Car vehicle)
{
// ...
}
}

Abstract class with all methods abstract - Practical Example

I am asking a very basic question and it may be marked duplicate (I could not find the answer though):
Is there any practical example of an Abstract Class with all the
methods declared as Abstract?
In most cases and as mentioned in Java Tutorial also, class with all methods abstract shall be an interface.
But since abstract class and interface are two different concepts, I am looking for an example compelling to have "complete abstract class"
The only practical approach i think is that Abstract class can hold state. So you can have inside properties with access level protected, and you can make protected abstract methods that in interface you can't cause all are public.
A practical example could be for example this, the protected method in java has 'inheritance access' and 'package access'.
public interface Operation{
void operate();
}
public abstract class AbstractClase implements Operation{
protected Operation delegate;
public AbstractClase(Operation delegate){
this.delegate=delegate;
}
//delegate implementation responsability to children
protected abstract doSomething();
}
The downside of using abstract class is that you loss the possibility to extends of something else too.
As well as for holding state, it's worth remembering that all interface members are implicitly public. So restricting visibility of abstract methods may itself be a compelling enough reason to use an abstract class instead of an interface.
Adding to the two answers given above, Interfaces can only have constants(Variables which are public,static and final) while there is no such restrictions for abstract classes.
Abstract classes can have constructors which will be implicitly called when a child class is instantiated (if it is non-parameterised). But this is not possible with interfaces.
Here is an example for the usage of an abstract class
abstract class Animal{
public int noOfLegs;
public boolean isAlive;
Animal(){
isAlive = true;
}
public abstract void walk();
}
class Cow extends Animal{
Cow(){
noOfLegs = 4;
}
public void walk(){
if(isAlive){
//Code for walking
}
}
}
One other general purpose of an abstract class is to prevent an instance of the class., for example
abstract class Mammal{
int i=0;
}
public class Man extends Mammal{
public setMeValue(int i){
this.i=i;
}
public static void main(String args[]){
Mammal m= new Man();
man.setMeValue(10);
}
}
In the above code, I effectively make sure that there will never be an object of instance Mammal.
An interface can be applied to wildly different classes. Classes that have no relation to each other are Serializable or Cloneable. However, subclasses of an abstract class are all related. This may not mean anything when implementing the interface or extending the abstract class, but it means something semantically.
There is a style of programming where all the methods of a base class are either public final, protected abstract, protected and empty, or private. But even that isn't what the OP was interested in.
Adding more to the below answers:
Interface provide you with a contract to implement where abstract Class may provide you with a template as well. For a simple scenario you can use an Interface or an abstract Class without thinking much. But having an abstract class just for maintaining a state might give you lot of problems in a complex implementation. In such cases you have to carefully consider what you really want to achieve in your code and make the decision. If you consider the case of maintaining the state in your code, you can always use the State pattern in your implementation, so you will be able to use an interface in your code. You should always consider the extend-ability and maintainability of your code before deciding to use an abstract class over interface.
The simplest practical example I can think of is a class that has a protected variable:
public abstract class RoadVehicle {
protected int numberOfTires;
protected String vinNumber;
protected VehicleRegistration registration;
public abstract void drive();
public abstract double calculateToll();
public abstract void changeTires();
// so on and so forth...
}
You can't do this with an interface.
public abstract class animal{
public abstract void speak(){
System.out.println("animal voice");
}
}
public class dog extends animal{
public void speak(){
System.out.println("dog voice");
}
}
The biggest motive behind having Pure Abstract classes is to allow future extension. Assume you have an Abstract class (with all abstract members), then you inherit that abstract class in 20 derived classes. Sometime in future you wish to add a public method to 5 of your derived classes, what do you do ?
Since you already inherit the abstract class, an easier solution is to add the method (with implementation) to the abstract class. This way you don't have to touch any of the derived classes. Interfaces are very rigid in this context, once created there is very little chance to change an Interface, as it would require changing all the classes that implement that Interface.

What do you do when a subclass can't implement an interface method because the superclass has a final method with the same signature?

Let's say you have a class that extends Activity and implements MyInterface, where Activity contains public final void setProgress(int progress) and MyInterface contains public abstract void setProgress(int progress)
I need to override the method from the interface, but I can't because Activty says it's final and can't be overridden.
What do I do?
Example:
public class MyActivity extends Activity implements MyInterface
{
#Override
protected void onCreate(Bundle bundle)
{
//stuff goes here
}
//Cannot override the final method from Activity
#Override
public void setProgress(int progress)
{
}
}
Let's also extend this question and say you don't have access to the source of MyInterface to change it, what does one do in such situations?
Use a decorator Design Pattern.
and here's a simplified example of the decorator pattern.
(adapted from the interwebs and polygenelubricants' answer on SO)
Note: before we begin remove the abstract keyword from the interface, that's wrong syntax
The class hierarchy is restructured as static inner classes so that the whole example is contained in one compilation unit (as seen on ideone.com):
Here's a diagrammatic overview of intended class hierarchy
public class AnimalDecorator {
static interface Animal {
public String makeNoise();
public void wagTail();
//other methods
}
static class Dog implements Animal {
public final String makeNoise() { return "woof"; }
public final void wagTail() { //do wag tail action }
}
static class DogDecorator implements Animal {
//delegate
private Animal animal;
public DogDecorator (Animal animal){this.animal = animal;}
public String makeNoise() { animal.makeNoise();}
public void wagTail() { animal.wagTail();}
}
static class LoudDog extends DogDecorator {
#Override public String makeNoise() {
return "WOOF WOOF WOOF!!!";
}
}
}
So here we have a simple Animal hierarchy, with Dog subclass. We also have a DogDecorator decorator -- also an Animal -- that simply delegates all methods to another Animal. That is, it doesn't really do any effective decoration, but it's ready to be subclassed so that actual decorations can be added.
We only have two methods here, makeNoise() and wagTail(). We then create the class we want LoudDog and use it. (Consider the case where Animal has many methods; then Normal would be most valuable).
Note that we can even stack one decoration on top of another. The exact implementation details may vary, but this simplified example pretty much captures the essence of the decorator pattern.
Steps
Subclass the original "Component" class into a "Decorator" class (see UML diagram);
In the Decorator class, add a Component pointer as a field;
Pass a Component to the Decorator constructor to initialize the Component pointer;
In the Decorator class, redirect all "Component" methods to the "Component" pointer; and
In the ConcreteDecorator class, override any Component method(s) whose behavior needs to be modified.
See also
Effective Java 2nd Edition, Item 18: Prefer interfaces to abstract classes
Related questions
Interface vs Abstract Class (general OO)
Is it just me or are interfaces overused?
You cannot override the final method because in the Java programming language, the final keyword is used to define an entity which cannot later be changed.
form Java Language Specification
Never tried but can give it a try.
You must implement the MyInterface in subclass too and can override the setProgress method of MyInterface and not of its superclass.
Should say..a good question:)
Edit:
In this case, the class cannot override the final method. So either your interface will have the exact same signature as the parent class (hence the interface is implemented automatically by inheritance), or you create a method with a different name.
The solution would largely depend on the circumstances, there's no textbook solution here.
Don't have your MyActivity implement MyInterface and instead create anonymous or inner class that implements it.
This ways you still have access to all MyActivity components and functions from setProgress(int) which is completly separate from final Activity.setProgress(int).

Categories