For instance, I have an abstract class implemented like this:
public abstract class Animal
{
public abstract void makeNoise();
}
and I have a child class which is representing an animal that does not make any noise. Which is better?
public class Turtle extends Animal
{
// properties and methods
public void makeNoise()
{
//leave it empty
}
}
or should i simply make it : public abstract void makeNoise(); inside Turtle?
It is better to move the makeNoise() method out of Animal as all the animals doesnot make noise. So create another interface NoiseMaker and add the the makeNoise method inside that.
public abstract class Animal {
// animals methods
}
public interface NoiseMaker {
void makeNoise();
}
public class Turtle extends Animal {
// properties and methods which are applicable for turtle
}
And when you want an animal which makes noise like Lion you can extend Animal class and implement NoiseMaker, so that it has the behaviour of Animal as well as it makes noise.
public class Lion extends Animal implements NoiseMaker {
public void makeNoise() {
// implementation
}
// other properties and methods which are applicable for turtle
}
What people often do: throw some sort of exception, like UnsupportedOperationException or something alike.
But: in the end your are fixing a symptom here.
The point is: extending a base class means that an object of the derived class IS-A object of the base class as well. And you are asking: how to violate the public contract of the base class.
And the answer is: you should not do that. Plain and simple.
Because if you start throwing exceptions here, all of a sudden, a caller that maybe has List<Animal> animals can't simply invoke makeNoise() on each object. The caller has instead to use instanceof (so that he can avoid calling makeNoise() on specific classes) - or try/catch is required.
So the real answer is: step back and improve your model. Make sure that all methods on the base class make sense for derived classes. If not - maybe introduce another layer, like abstract class NoisyAnimal extends Animal.
This is the best use case to use UnsupportedOperationException
You have to implement because of the abstract design. So just implement the method and throw UnsupportedOperationException exception.
Keep it Animal, cause most of the Animal's make sound :) If you move it to Turtle, all the subclasses again have to have their own voice method.
or should i simply make it : public abstract void makeNoise(); inside Turtle?
If you do, Turtle is abstract. So the question isn't which is better, the question is, do you want to be able to instantiate Turtle or not?
If you do, you have to implement the method.
If you are okay with it being abstract, then declare it abstract and don't list the method at all:
public abstract class Turtle extends Animal {
}
You might want to distinguish between Animals making noises or not. Something a long the lines of
public abstract class Animals {}
public abstract class AnimalsNoisy extends Animals { abstract void makeNoise(); }
You would then use Turtle extends Animals. The advantage of this structure is if you have a List of Animals you don't need to worry if they implemented the makeNoise method or not e.g.
for(AnimalsNoisy animal: ListAnimalsNoisy) { animal.makeNoise();}
It is a good example to learn how to make your code loosely coupled.
By loosely coupled I mean, if you decide to change or modify your code you will not touch your previous code. Sometimes it is referred as OPEN-CLOSE principle.
For this first you have to identify what part of your code is frequently changing.
Here the method makingNoise() will have different implementation based on your class.
This design can be achieved in following steps.
1) Make an interface which will have implementation for makeNoise()
method.
public interface NoiseInterface {
public void speak();
}
2) Create concrete implementation for NoiseInterface
eg: For Fox
public class FoxSound implements NoiseInterface {
#Override
public void speak()
{
//What does the fox say ?
Sysout("chin chin chin tin tin tin");
}
}
3: Provide the Noise Interface in Animal Class
public abstract class Animal
{
public NoiseInterface noiseMaker;
public abstract void makeNoise();
}
4: Just provide the Type of NoiseInterface of your choice in Fox Class
public class Fox extends Animal
{
public Fox()
{
noiseMaker = new FoxSound();
}
public void makeNoise()
{
noiseMaker.speak();
}
}
Now Amazing thing about this design is you will never have to worry about the implemetation. I will explain you how.
You will just call
Animal me = new Fox();
fox.makeNoise();
Now in future you want to mute the Fox.
You will create a new Interface Mute
public class Mute implements NoiseInterface {
#Override
public void speak()
{
Sysout("No sound");
}
}
Just change the NoiseBehavior in Fox class constructor
noiseMaker = new Mute();
You can find more on OPEN-CLOSE Principle Here
You may write like this,is this what you want?
public interface NoiseInterface {
void makingNoise();
void makingNoNoise();
}
public class Animal implements NoiseInterface{
#Override
public void makingNoise() {
System.out.println("noising");
}
#Override
public void makingNoNoise() {
System.out.println("slient");
}
}
public class Turtle extends Animal{
#Override
public void makingNoNoise() {
System.out.println("turtle");
super.makingNoNoise();
}
}
Related
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.
I have an interface that has 4 methods and a class that implements the interface. Here comes the question: "How can I inherit from the interface only 2 of those methods and my class don't became abstract?"
interface Class1 {
void method1();
void method2();
void method3();
void method4();
}
public class Class2 implements Class1 {
#Override
public void method1() {
}
#Override
public void method2() {
}
}
You have to get tricky, and you have to lookup why this works, especially if it's an interview question. It's basically for compatibility (the default methods in the interface), and requires Java 8.
public interface One {
void method1();
void method2();
void method3();
void method4();
}
public interface Two extends One{
default void method1(){}
default void method2(){}
}
public class Three implements Two{
#Override
public void method3() {}
#Override
public void method4() {}
}
Non-abstract Three.class implements method3 and method4 of One.class without defining method bodies for method1 and method2. Method1 and Method2 are defined with default implementations in interface Two.class.
You don't.
Somewhere in your inheritance chain those methods need to be implemented. That's the purpose of interfaces.
If you are using Java 8, there are new default implementations in interfaces, take a look at this page for details and that might help your case, barring that you need to have your concrete class inherit from an Abstract that provides an implementation for those 2 unwanted methods (even if its to print a cheerful "//TODO") message or remove them form the interface.
Firstly, you would get all the methods from the interface and wouldn't skip any. Then you have to implement the methods to satisfy interface contract. So it is better in your case to make 2 different interfaces and use them as you can implement multiple number of interfaces for a class.
interface ClassA {
void method1();
void method2();
}
interface ClassB {
void method3();
void method4();
}
An interface is used when you want a set of programs to follow a certain trend or acquire a common set of properties. These properties are declared as methods in the interface. An interface can have abstract methods only and it is compulosory to inherit these methods and define them some where down the inheritance line.
An abstract method would look like:
public void hello();
It has no method body. You need to inherit it and define the method body.
Let us consider an interface animal.
public interface animals
{
public void walks();
public void eats();
public void sleeps();
public void dog_breed();
public void barks();
}
Let us consider 2 classes named Jimmy_the_dog and Tom_the_cat.
We would want the these 2 classes to implement the interface animal to give it the properties of animals. But the problem is with the abstract methods barks() and dog_breed() in the interference. A dog can have all the properties mentioned in the interface animal but it does not make sense for a cat to inherit the methods barks() and dog_breed().
This is where we will split the interface. Here, we will split the animal interface to a dog interface and animal interface. Therefore, the properties in interface animal would become more common to animals in general.
public interface animals
{
public void walks();
public void eats();
public void sleeps();
}
public interface dog
{
public void barks();
public void dog_breed();
}
How to work around with the above two interfaces?
public class Tom_the_cat implements animal
public class Jimmy_the_dog implements animal implements dog
Jimmy_the_dog implements both the interfaces to acquire dog specific properties. Any animal which is a dog can do so. Similarly, you could make cat specific interfaces too for all the cats in the world.
The above interface could work in the following manner too:
public interface dog extends animal
public class Jimmy_the_dog implements dog
Jimmy_the_dog gets all the animal and dog properties.
Note:
A class can extend a single class only but it can implement multiple interfaces.
You can't do that. It comes down to what the implements keyword implies about a class.
An instantiable class cannot implement an interface without having all the methods of the interface implemented. If you don't implement all the required methods, you have to declare the class abstract or you have to remove the implements declaration.
This question already has answers here:
Work around the need to override abstract methods in Java?
(2 answers)
Closed 7 years ago.
In my Project I have an abstract class that contains couple of abstract methods. Now multiple other classes extend that abstract class. Not all classes wants to override all the method of abstract class because that are not useful to them. How can I provide default implementation of those methods inside subclasses that aren't useful for the class?
Example-:
public abstract class Animal
{
public void Action()
{
.....
this.roar();
}
public abstract void roar();
public abstract void run();
}
Above is the abstract class that is going to have abstract methods that subclasses would implement.
public class Lion extends Animal
{
#Override
public void roar()
{
s.o.p("Lion roars");
}
#Override
public void run()
{
s.o.p("Lion runs");
}
}
public class Deer extends Animal
{
#Override
public void roar()
{
// Question : What should I do here?
}
#Override
public void run()
{
s.o.p("Deer runs");
}
}
EDIT-:
Thanks for suggestions, I understand the idea of having another class which can have method that aren't common ("roar" in this case).But My Project structure is a bit different and its kinda legacy code in which numerous subclasses extends from Animal class. Subclasses call a concrete method which in turn call abstract methods("roar" in this example, Please see updated Animal class with concrete method "Action").
Now as you suggested if I created another abstract class
public abstract RoaringAnimal extends Animal
{
public abstract void roar();
}
This will solve one of the problem as I can now just extent RoaringAnimal instead if Animal but other classes which calls Animal.Action method, they won't find implementation of roar() inside Animal and javac will complain.
If you have a method that is appropriate for a subclass but not for a superclass, like the roar method here, then you may want to provide another abstract class that subclasses Animal but provides roar, say, RoaringAnimal. The roar() method would no longer be declared in Animal, but in RoaringAnimal.
public abstract class RoaringAnimal extends Animal
{
public abstract void roar();
}
Then you can have Deer extend Animal, not implementing roar(), but you can have Lion extend RoaringAnimal, implementing roar().
Traditionally you do this:
#Override
public void roar()
{
throw throw new UnsupportedOperationException();
}
This exception was created for this purpose actually
#rgettman answer is more suitable though! try not to use this method ;) But know that it exists, You can find some examples in core Java libs
In such a case use an Adapter class. The adapter class will be a concrete class that extends your abstract class, but It will basically implements its methods with nothing or its methods implementation can throw an exception that extends RuntimeException.
There is a very nice example of this in Awt with the MouseAdapter class. See the javadoc here
Here is an example:
class AnimalAdapter extends Animal {
#Override
public void roar() {
throw new NotImplementedException();
}
#Override
public void run() {
}
}
A Sheep class for exemple will extend AnimalAdapter, but will get a RuntimeException only if it tries to call roar.
class Sheep extends AnimalAdapter {
#Override
public void run() {
System.out.println("I am a sheep I run, but I don't roar...");
}
}
Exemple of such an exception
class NotImplementedException extends RuntimeException {
}
One common solution are classes called Adapter classes. Those will implement all methods with a standard (or empty) implementation and you override the ones you want to change. The downside is, you don't know if the animal can do this or that.
Another possibility would be to split the abstract class into interfaces. Each set of methods that usually is combined together is put into one interface. The class will then implement the interfaces or not. This can end up in having feature interfaces for your animals (Roaring, Running, Crawling, ...), the animal implementation will then implement the interfaces it can fulfill. Dependencies between interfaces can be build by interface inheritance.
On Java8, there is the possibility to have default methods for interfaces, that could also be used for your classes. Instead of using the abstract baseclass, you use an interface with default methods.
Assume an abstract class has only abstract methods declared in it and the interface has abstract methods.
How does this affect the abstract method m?
abstract class A {
abstract void m();
}
interface A {
abstract void m();
}
Even if the abstract class is a pure abstract, i.e. contains only abstract methods and does not contain state, your subclass extends this class and therefore you have single inheritance only.
However you can implement several interfaces.
Therefore if you want to force your classes to be a subclass of your A and not to be subclass of something else, use abstract class. Otherwise define interface.
Interfaces are also more useful when you don't exactly know if all your entities will need to override a specific method. Consider for instance birds, some can fly and some can't. You don't want to force overriding a fly() method in all Bird subclasses.
public abstract class Bird(){
...
public abstract void eat(); //all birds eat
public abstract void sleep(); //all birds sleep
public abstract void fly(); //is wrong here since not all birds can fly
}
A more correct way would be to define interfaces for specific cases, so in this case
public interface Flyable{
abstract void fly();
}
Then you can define your subclasses as birds that can fly or not based on the fact they implement the Flyable interface or not.
public class Eagle extends Bird implements Flyable{
#override
public void fly(); //needed
-----
}
public class Ostrich extends Bird{
//does't fly
}
A "High-Level" component is a class with behavior defined in terms of other "low level" components. Example of this is Bulb class needs Socket class to implements its LightOn() behavior.
Not all superclass is the high-level component and not all subclass is the low-level component. Because of the following examples.
Template method pattern from head first design pattern.
public abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring int cup");
}
}
public class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("Dripping Coffee through filter");
}
public void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
}
In this example CaffeineBeverage class has a behavior prepareRecipe(). This behavior needs subclass implementation of brew() and addCondiments().
so... this means here CaffeineBeverage (superclass) is the high-level component and Coffee (subclass) is the low-level component.
public class superClass {
public go() {
//super class implementation
}
}
public class subClass extends superClass {
public go() {
//sub class implementation
}
}
In this case superClass didnt need subclass to implement its go() method.
Even if a class has abstract method that needs the subclass to implement it DOESNT mean super class is the high level component. See example below.
public abstract class superClass {
public abstract go();
}
public class subClass extends superClass {
public go() {
//subclass implementation;
}
}
main() {
superClass s = new subClass();
s.go();
}
Here s is not superClass object... s here is the subClass object.
Is it right to say that not all superclass is the high-level component of the subclass?
Yes it is right to say that ... assuming that you are using the word "component" the right way. In fact, as a general rule, inheritance does NOT model components.
For example:
public abstract class Mammal extends Animal {
....
}
public class Cat extends Mammal {
....
}
A Cat is not a "component" of a Mammal, and a Mammal is not a "component" of a Animal. This is not modelling a "composition" or "container" relationship. It is modelling a classification relationship; i.e. a Cat "is a" Mammal, and a Mammal "is a" Animal.
Your first example is a bit confusing / confused because the class names and methods have contradictory meanings (to my mind). But it looks like you are modeling beverage making devices. If that is correct then the relationship that you are really modelling is "is-a" not "component-of" / "part-of".
Finally, don't get stuck on the point of what classes and inheritance "means" in relation to the real world. In practice, Java classes are rarely used to directly model real world things. (You are unlikely to see classes that model cats and coffee-makers in real programs.) The true utility of inheritance is in its ability to provide structure for the code ... not in its ability to (crudely) model the real world.