I have come up with two different ways to implement a few methods in my class:
class Zoo {
public void addTiger(Tiger tiger);
public void addEmu(Emu emu);
// ...
}
class Zoo {
public void add(Tiger tiger);
public void add(Emu emu);
}
The only difference between the two, that I can see, is verbosity - but am I missing something more fundamental? Will one approach make something more difficult in the future?
What's the difference between adding a Tiger and adding an Emu? Why not make an Animal interface?
I would do something like:
class Tiger implements Animal { }
class Emu implements Animal { }
class Zoo {
void add(Animal animal) { }
}
Zoo zoo = new Zoo();
zoo.add(new Tiger());
zoo.add(new Emu());
But there won't be a big difference in your two approaches, they are both equally right or wrong, since the violate the SOLID principles.
If, in the future, you will decide to merge Emu and Tiger by making them both implement the same interface or extend the same class, and therefore merge the two methods, using
class Zoo {
public void add(Tiger tiger);
public void add(Emu emu);
}
will ease your job because you won't need to change anything in the places that use your method.
So yes, the first approach could make something more difficult in the future.
Base on context that you'are using.
In this context, that Tiger and Emu both is Animal. I prefer using overloading method, it will make sense. And, if Tiger and Emu both inherit from Animal class. You can declare an array of animal:
Animal[] zoo;
and this zoo both contains Tiger and Emu. You can do this :
for (int i = 0; i < zoo.length; i++) {
BigZoo.add(zoo[i]);
}
In OOP, we say this is polymorphism.
But, if those things are two different meaning. For example, A server has two things to add: User and Data. It makes sense :
addUser(User user);
addData(Data data);
rather than:
add(User user);
add(Data data);
Hope this help you :)
Related
This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 3 years ago.
I'm just getting started with interfaces and I cannot grasp the concept.
class Client {
IServer x = new Server();
void m() {
x.p();
}
}
interface IServer {
void n();
void p();
}
class Server implements IServer{
public void n() {
System.out.println("Methode n");
}
public void p() {
System.out.println("Methode p");
}
}
So client should be able to use the methods provided by server through the interface IServer.
Is IServer x = new server(); correct? The examples that I found (https://www.w3schools.com/java/java_interface.asp) all build interfaces and then the main class calls the other class without using the interface.
Thank you for your help, I guess I'm just missing something obvious here...
A good explanation of how interfaces work and why they're used can be done with the following example. Let's say we have a zoo object with animals. We want all the animals to be able to make a noise depending on what animal they are. We start with the following class:
public class Zoo {
private List<Animal> animals;
public Zoo() {
animals = new ArrayList<>();
}
public void addAnimal(Animal animal) {
animals.add(animal);
}
public void roar() {
for(Animal a : animals) {
a.makeNoise();
}
}
}
This is basically just an object containing a list of animals and we can add animals to this list. When we call the method roar we want all the animals to make their own noise and print it to the console. Now this is where interfaces are useful, since we know we will have multiple types of animals we can specify what a basic "animal" can do, these are generic traits that describe that they can do something but not how. For instance, a box and a human can both move, but a human can move on its own and a box cannot. Or maybe a human can move up stairs but a dog cannot. Knowing this, we create a basic interface describing that an animal can make a noise:
public interface Animal {
void makeNoise();
}
This will allow us to create as many animals as we want, while forcing them to implement our defined functionalities. So now, we can create some animals:
public class Cat implements Animal {
private String name;
public Cat(String name) {
this.name = name;
}
#Override
public void makeNoise() {
System.out.println(name + "said Meow");
}
}
public class Dog implements Animal {
#Override
public void makeNoise() {
System.out.println("Woof");
}
}
As you can see, we can give both classes their own functionality, while still enforcing both classes to at least be able to make their respective noise. In this case a cat can have a name, while a dog cannot. This means that we can now fill our Zoo with any animal we want, and since they all have the same overlaying interface we don't have to, for instance, create more than one Collection to store each type of animal. We can just throw them all on one big pile based on their interface and we can call the proper method through the interface:
public void run() {
Zoo zoo = new Zoo();
zoo.addAnimal(new Cat("Bob"));
zoo.addAnimal(new Dog());
zoo.addAnimal(new Cat("William"));
zoo.roar();
}
As far as types are concerned. It works like it does in real life. Following our example, a dog is an Animal, but an animal is not necessarily a dog. Since our code in this case (when it's inside the zoo) only knows that it has Animals, but not what specific types, it only allows us access to the functionalities defined in the interface.
This means that, we are allowed to do stuff like:
Animal a = new Dog();
Dog b = new Dog();
Animal c = new Cat("Bob");
Cat d = new Cat("Wilbert");
But not:
Animal a = new Dog();
Dog b = a;
Since, as soon as we assign a and say "you're of type animal" it doesn't know if the data inside a is actually a dog or not.
A better documentation is the official at https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
There are a number of situations in software engineering when it is important for disparate groups of programmers to agree to a "contract" that spells out how their software interacts. Each group should be able to write their code without any knowledge of how the other group's code is written. Generally speaking, interfaces are such contracts.
With an Interface, you can enforce a Class to have a particular behavior, defined inside the Interface, BUT implemented inside the class that implement that Interface.
And also, if you know that an object Dog implements the Interface Run and that Interface declare the method run() {}, you can safely invoke the method run on the object Dog, because it contains the method implementation:
Interface Run
{
public void run();
}
class Dog implements Run
{
public void run()
{
// the dog is running
}
}
Dog dog = new Dog();
dog.run();
I'm new in design patterns and now I am learning about Factory Method pattern. I try to make an example using animals.
I have an Animal interface with two methods, breathe and walk. Implementing this interface I have two classes, Giraffe and Flamingo.
Following the pattern I have two factories, one for Giraffes and one for Flamingos and a main class like this:
if (color.equals("yellow")) {
factory = new GiraffeFactory();
} else {
factory = new FlamingoFactory();
}
Animal animal = factory.createAnimal();
animal.breathe();
animal.walk();
This works perfectly but now I realise that Flamingos can fly. I don't want to include this method in Animal interface because Giraffes can't.
How can I call this new method only in Flamingo Animal instances? Is cast the only solution? Or is this pattern only for objects that has the same methods from their interface?
((Flamingo) animal).fly();
Thank you so much.
Well the usage of this pattern wouldn't make much sense, the whole point is that you don't know what implementation of Animal you will get (responsibility separation), so it would be a total anti-pattern to use the knowledge. You can make a new interface Winged or something, and make Flamingo implement it. Then you can always check. remember that bats also fly when thinking of a name ;)
if (animal instanceof Winged) {
Winged winged = (Winged) animal;
winged.fly();
}
You can create another interface called WingedAnimal that extends Animal.
public interface WingedAnimal extends Animal {
public void fly();
}
public class Flamingo implements WingedAnimal {
#Override
public void breath() {}
#Override
public void walk() {}
#Override
public void fly() {}
}
Then write this code while creating Flamingo instance:
WingedAnimal animal = (Flamingo) factory.createAnimal();
Your code animal.fly() will work perfectly.
You can use s factory method using generics. A couple of good examples are available
Here in C#
Here always in C#
Here in java.
I suggest you read all of them for a good understanding of the problem and possible solution approaches.
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 know there are lots of post regarding this question which has theoretical explanation with real time examples.These OOPs terms are
very simple but more confusing for beginners like me.
But I am expecting here not a definition and real time example BUT expecting code snippet in java.
Will anyone please give very small code snippet for each one in Java that will help me a lot to understand Encapsulation vs Information Hiding vs Abstraction vs Data Hiding practically?
Encapsulation = information hiding = data hiding. Information that doesn't need to be known to others in order to perform some task.
class Bartender {
private boolean hasBeer = false;
public boolean willGiveBeerToDrinker(int drinkerAge) {
return (hasBeer && (drinkerAge >= 21));
}
}
class Drinker {
private Bartender bartender = new Bartender();
private int age = 18;
public boolean willBartenderGiveMeBeer() {
return bartender.willGiveBeerToDrinker(age);
}
// Drinker doesn't know how much beer Bartender has
}
Abstraction = different implementations of the same interface.
public interface Car {
public void start();
public void stop();
}
class HotRod implements Car {
// implement methods
}
class BattleTank implements Car {
// implement methods
}
class GoCart implements Car {
// implement methods
}
The implementations are all unique, but can be bound under the Car type.
To reduce the confusion:
Encapsulation is used for Information hiding or data hiding
Encapsulation means self contained. All the objects in Java have a set of data and methods to operate on that data. So the user of any object does not have to worry about the about how the obect is working. This way you hide the information and other complexities.
Example: Any Java object is enough to represent an example.
Abstraction: This means making things general i.e., instead of creating a very specfic class when you create base classes or interfaces and then extend them to get your specific class.
Example:
class Animal {}
class Lion extends Animal{}
So here for Lion class you have a generalized class i.e., Animal. This represents abstraction
Note Examples givien by KepaniHaole are perfect.
Abstraction Example:
public interface Animal{
public String getType();
}
class Lion implements Animal {
private String animalType = "WILD";
#Override
public String getType() {
return this.animalType;
}
}
class Cow implements Animal {
private String animalType = "Domestic";
#Override
public String getType() {
return this.animalType;
}
}
In this example the Lion and Cow classes implements the Animal interface. The Lion and Cow classes override the getType method of the Animal interface.
Here Lion and Cow are special cases and Animal is more generalized. So this gives you abstraction because whenever you have an Animal you have the getType method to know its type i.e., you have generalized it.
Now if you notice I have made the animalType as private in the Lion and Cow classes so that nobody outside the class can modify it. This way I am hiding unwanted information from outer objects.
All the outer objects need is the getType method to known the type of the animal. This way I am exposing only relavent information to outer objects.
I wonder why it is allowed to have different type of object reference?
For example;
Animal cow = new Cow();
Can you please give an example where it is useful to use different type of object reference?
Edit:Cow extends Animal
This is at the heart of polymorphism and abstraction. For example, it means that I can write:
public void handleData(InputStream input) {
...
}
... and handle any kind of input stream, whether that's from a file, network, in-memory etc. Or likewise, if you've got a List<String>, you can ask for element 0 of it regardless of the implementation, etc.
The ability to treat an instance of a subclass as an instance of a superclass is called Liskov's Substitution Principle. It allows for loose coupling and code reuse.
Also read the Polymorphism part of the Java tutorial for more information.
On a simpler note, this enables polymorphism. For example you can have several objects that derive from Animal and all are handle similar.
You could have something like:
Animal[] myAnimal = {new Cow(), new Dog(), new Cat()};
foreach (Animal animal in myAnimal)
animal.Feed();
The Feed() method must then be overriden within each child class.
By the way, code is C#-like but concept is the same in Java.
This is basically a concept of standardization.
We know that each animal have some common features. Let us take an example of eating and sleeping, but each animal can have different way of eating or sleeping ... then we can define
public abstract class Animal
{
public abstract void Eat();
public abstract void Sleep();
}
//Now Define them in various classes..
public class Cow extends Animal
{
pubic void Eat()
{
//process of eating grass
}
public void Sleep()
{
//process of sleeping
}
}
public class Lion extends Animal
{
public void Eat()
{
//process of eating flesh
}
public void Sleep()
{
//process of sleep
}
}
Now you do not have to define different objects to different classes... just use Animal and call generally
public class MyClass
{
public static void main(String[] args)
{
Animal _animal = new //think the type of animal is coming dynamically
//you can simply call
_animal.Eat();
_animal.Sleep();
// irrespective of checking that what can be the animal type, it also reduces many if else
}
}
This is called polymorphism and it's one of the most powerful aspects of Java.
Polymorphism allows you to treat different objects the same.
It's a great way to create re-usable, flexible code.
Unfortunately it's a part of Java that new programmers often take awhile to understand.
The example you've provided involves inheritance (extending a class).
Another way to enjoy the benefits of polymorphism is to use interfaces.
Different classes that implement the same interface can be treated the same:
class Dog extends Animal implements Talker {
public void speak() {
System.out.println("Woof woof");
}
}
class Programmer implements Talker {
public void speak() {
System.out.println("Polymorphism rocks!");
}
}
interface Talker {
public void speak();
}
public static void testIt() {
List<Talker> talkerList = new ArrayList<Talker>();
talkerList.add(new Dog());
talkerList.add(new Programmer());
for (Talker t : talkerList) {
t.speak();
}
}
Simply putting all Cows are Animals. So JAVA understands that when Cow extends Animal, a Cow can also be called as Animal.
This is Polymorphism as others have pointed out. You can extend Animal with Dog and say that Dog is also an Animal.
In another class/method you might want to use different implementations of the same interface. Following your example, you might have something like:
public void feed( Animal animal ) {
animal.getHome().insertFood(animal.getFavFood());
}
Now you can implement the details in your animal classes and don't have to extend this method anytime you add a new animal to your programm.
So in some cases you need the common interface in order not to implement a method for each implementation, whereas on other occasions, you will need to use the explicit implementation.
This is an inheritance 101 question.
It allows objects that share common functionality to be treated alike.
It also allows specific implementations to be supplied at runtime that are subclasses of an abstract type.
I could probably ramble on for ages. Perhaps thus question is just too broad to answer here.