about OOP and inherited classes - java

im new here...
i have a little question regarding OOP rules.
let's say we have 3 classes:Bird,Cat & dog.
for both dog and cat have a fourlegs() method, and all of them have an eat() mathod.
what is the best way to accomplish this task:
*create Animal class with eat(), create Pet class with fourlegs() which will inherit from Animal class.
after then,cat &dog classes inherit from Pet while bird only inherit from Animal.
*since that there are differenet mathods for several classes object-oriented is not relevant here.
thank you very much!

I think you almost answer your own question. Create a class-hierarchy with the "Animal"-interface as the top-node.
I made an example of the hierarchy here.
Also, inheritance and polymorphi is some of the essentials of OOP, so I don't get your last sentence.

You could make a interface / abstract class Animal. Bird, Cat and Dog inherit from Animal.
Since the number of legs is something that cannot be categorized by making them depend on Mammal, Pet or something else, I would define an interface FourLegged. This would also enable you to not bind fly() to bird... there are birds that can't fly and insects that can fly:
public abstract class Animal {}
public interface FourLegged {}
public interface Flyer {}
public class Dog extends Animal implements FourLegged {}
public class Bird extends Animal implements Flyer {}
It depends on your needs whether Animal is an interface or an abstract class.

You could use the following sample code:
Declare class Animal
class Animal(){
void eat(){
... do something ...
}
}
Declare class Pet
class Pet() extends Animal{
/* This class has inherited eat() method as declared in class Animal.
If you want to change it, you must use #Override. */
void fourlegs(){
... do something ...
}
}
Declare classes Dog and Cat
class Dog extends Pet{
/* This class has inherited both eat() and fourlegs() from class Pet. */
...
}
and the same for class Cat.
Declare class Bird
class Bird extends Animal{
/* This class has inherited eat() method as declared in class Animal.
...
}
OOP programming is certainly related to this exercise, as you need to use inheritance (which is one of OOP's characteristics) in order to accomplish it.

Related

Marker Interface vs Enums

I am trying model a zoo.
Suppose I have the following structure for areas in the Zoo(omitted some details)
public abstract class AnimalHabitat{
private ArrayList<Animal> animals = new ArrayList<>();
public void setAnimal(Animal animal) {
animals.add(animal)
}
}
public class Enclosure extends AnimalHabitat{}
public class Aquarium extends AnimalHabitat{}
public class Cage extends AnimalHabitat{}
Then I have the following structure for animals
public abstract class Animal{}
public class Lion extends Animal{}
public class Zebra extends Animal{}
public class Shark extends Animal{}
public class Starfish extends Animal{}
public class Parrot extends Animal{}
public class Eagle extends Animal{}
I want to add an animal to its corresponding appropriate habitat. To simplify code I was thinking to use either a marker interface, such as
public interface TerrestrialAnimal{}
public class Lion extends Animal implements TerrestrialAnimal{}
public class Zebra extends Animal implements TerrestrialAnimal{}
and then I will be able to do
public class Zoo{
public boolean addAnimal(AnimalHabitat habitat, Animal animal) {
if (animal instanceOf TerrestrialAnimal && habitat instanceOf Enclosure) {
habitat.set(animal);
return true;
}
if (animal instanceOf AquaticAnimal && habitat instance of Aquarium) {
habitat.set(animal);
return true;
}
// So for aerial
}
}
However an alternative is to use enums. For example suppose I have
public enum AnimalType{
Terrestrial, Aquatic, Aerial;
//getter
}
Then in the Animal abstract class I can define
public abstract class Animal{
private AnimalType type;
// Initialise in the constructor depending on the animal instance
}
And I will do the same in the addAnimal() method in Zoo.
What are the pros and cons of each approach? Thanks!
I would use enums. You don't need all of those if statements.
Just have the attribute type in both Animal and AnimalHabitat and then compare them.
if (animal.getType() == habital.getType()) { // can add to habitat
Switch to interfaces if you want to add some methods to the interface specific to the animal type.
Enum
pros:
Easy to scale: You can easily add value
More coincise: You have one single file to define all AnimalType
More readable: definitely readable
More Flexible: You can define method on Enum and you can print AnimalType using enum value
Comparable: You can do simple compare instead of using instanceof
with enums approach i doesn't find any cons.
Interface
pros
Methods: You can define common methods signatures
You can use 2 interfaces in same Animal (may an animal have more habitat? Or more types?)
you can use interface as supertype in collections/class variable
cons
Expensive: definitely expensive, one interface for each type
In your example i prefer Enums because you are using interfaces to define animal types and it can be done easily using Enums. Use interfaces if you need to define common method signatures or you want to use Interfaces as supertype as follow:
List<TerrestrialAnimal> terrestrialAnimal = new ArrayList<>(); it can contains all terrestiral animal.

Java Inheritance with generics

Can somebody explain (like for dummies) the following examples of inheritance in Java:
1) public class Dog <T extends Animal> {....
2) public class Buldog extends Dog<DogFood, DogCommands> {....
3) public class Buldog<T extends DogFood, K extends DogCommands> extends Animal implements LivingBeign, LivingThing<T,K> { ....
1) public class Dog <T extends Animal> {...
There will be an generic type In your Dog class which is inherit variables and methods from class (probably an abstract class Animal)
This T must have and animal property.. For example assume you have a class Mammalian. We know that all mammalian are animal so they have what all animals have, and they can what all animals can.
So yo can call this as
public Dog<Mammalian> myDog = ...
There is a different situation.
2) public class Buldog extends Dog<DogFood, DogCommands> {....
So your dog class should be written like
/** T refers the food, and K refers commands*/
public class Dog<T,K> {....
So when you want to extend your class with Bulldog, you can leave generic or specify those generic types..
3) public class Buldog<T extends DogFood, K extends DogCommands> extends Animal implements LivingBeign, LivingThing<T,K> { ....
This is also as easy as above codes. The difference that you are desiring subclass of DogFood, which can be anyting, it can be Pap or Milk or Meat, and some subclass of DogCommands for example SitCommand, PlayCommand.. And as you are creating Buldog you know that It is Animal, so you don't want to write animal's property and methods again and since in Java you can't multiple inherit, you want also the other interfaces methods in your class..
I hope it is more understandable now.

How do you create a subclass so that the parameters are of the subclass type in Java

I have the abstract parent class Animal:
public abstract class Animal
{
public abstract <T extends Animal> T copyAnimal(T animal);
}
I then want to create a subclass Duck but to override the copyAnimal I want to use Duck as the parameters such that:
public class Duck extends Animal
{
#Override
public Duck copyAnimal(Duck duck)
{
return copyOfDuck;
}
}
This of course gives me a compiler error saying that the method is not overridden. That being said how can I adjust this code so that I don't have to pass Animal to the copyAnimal() method to save casting, etc. since it looks ugly and would require additional runtime checks. Or is it even possible? And if not then what's the most elegant solution?
public abstract class Animal<A extends Animal<A>>
{
public abstract A copyAnimal(A animal);
}
Then:
public class Duck extends Animal<Duck>
Note that you can't constrain it to be the "self" type (e.g. it could be Duck extends Animal<Pig>); you just have to only declare the classes you want to declare.

'Extends' and 'Implements' Java equivalents in C#

What is the C# equivalent syntax for the following Java statement:
public class Lion extends Animal implements Diurnal()
{
}
Animal is Base class
Diurnal is an Interface
the inheritance could be declared like this.
public class Lion : Animal, Diurnal
{
}
In C#, you can inherit one base class and can be multiple Interfaces.
One more tip, if you are making an Interface in C#, prefix it with I. eg IDiurnal
public class Lion : Animal, // base class must go first
Diurnal // then interface(s) if any
{
}
Would look something like this:
public class Lion :Animal, Diurnal {
}
Where Animal is a class and Diurnal is an interface.
Please note, that according to the C# naming convention, interface has to have "I" infront of its name, so finally it should look like this:
public class Lion :Animal, IDiurnal {
}
In C#, there is uniform syntax for extending class and implementing interface.
public class Lion : Animal, Diurnal {
}
you need to write down first base class like(Animal is base class),
lately interfaces like as(Diurnal is a Interface)
public class Lion : Animal, Diurnal {}
the first name after : is the extended class, after comes the implemented interfaces
public class Lion : Animal, Diurnal
{
}
c# do not allow multiple class extension, but you can implement many interfaces
public class Lion : Animal, Diurnal
{
}
interface Diurnal
{
}
class Animal
{
}
Class Animal was inherited by Lion class. Diurnal class is interface.

Java multiple inheritance issue

I have a question like this :
Think a scenario like this
public class Animal {
protected String Name;
Boolean canWork;
}
public class Dog {
Enum TailType
}
And I need to have both of this classes attributes in a class of the third level which extends the both classes .. but using interfaces I don't think this can be achieved. Is it possible to do this using a design pattern or some else method ?
Summary : I want to have attributes from two classes to a concrete class
You can have Dog extend Animal, then extend Dog by the third class, but unless your 3rd class is Poodle then you may have a problem you don't realize yet. That being inheritance is only appropriate when the relationship is a modeling criteria, and extending objects only to get their functionality is the wrong approach. Inheritance should follow the IS-A principle. That being your subclass IS-A base class in modeling terms. If it doesn't pass that test you are using inheritance when you shouldn't. After all you can use delegation to obtain their functionality. That meaning:
public class SomeClass {
private Dog dog;
public void bark() {
dog.bark(); // this is reusing the functionality without extending
}
}
Now SomeClass can call or invoke methods on Dog without extending it. Now the downside to this is a reference to Dog can't point to SomeClass, but if SomeClass is-not-a Dog that's probably good. However, if you have to allow Dog and SomeClass to share some typing so you can have a reference that points at either Dog or SomeClass then you can create an interface that both share:
public class SomeClass implements Barkable {
private Dog dog;
#Override
public void bark() {
dog.bark();
}
}
public class Dog implements Barkable {
#Override
public void bark() {
System.out.println( "Bark! Bark!" );
}
}
With delegation/composition and interfaces you DON'T need multiple inheritance. It's a really simple technique to apply and master and you'll build systems that are much more flexible than relying on inheritance alone.
if you are trying to have just attributes, I think you can use interfaces like:
interface A{
int a = 0;
}
interface B{
int b = 1;
}
class implements A, B{
//can access A.a and B.b
}
But this is not a good approach, interfaces are meant for contracts not just to contain constants (variables in interface are static and final by default)
For good reasons modern OO languages like Java and C# do not support multiple inheritance.
The replacement to use in most cases is the interface:
public Interface NameAndWorkable {
setName(String name)
String getName();
boolean canWork();
setCanWork(boolean canWork);
}
public Interface TailAnimal {
TailtypeEnum getTailType();
setTailType(TailtypeEnum tailtype);
}
public class Animal implements NameAndWorkable {
private String name;
private boolean canWork;
public setName(String name)
public String getName();
public boolean canWork();
public setCanWork(boolean canWork);
}
public class Dog implements TailAnimal {
private TailTypeEnum tailType;
public TailtypeEnum getTailType();
public setTailType(TailtypeEnum tailtype);
}
and now the third object with fullfills both Interfaces
public class WorkingNamedDog implements NameAndWorkable, TailAnimal {
private String name;
private boolean canWork;
private TailTypeEnum tailType;
// from NameAndWorkable
public setName(String name)
public String getName();
public boolean canWork();
public setCanWork(boolean canWork);
// from TailAnimal
public TailtypeEnum getTailType();
public setTailType(TailtypeEnum tailtype);
}
To achieve multiple inheritance, it is necessary to use Interfaces. You can either use inheritance by extending these classes on one another like:
//Your first class
public abstract class Animal{
//It is upto you to use an abstract method inside it. However it is not necessary to do so!
//define an abstract method inside an abstract class.
}
//Your second class
public class Dog extends Animal{
}
//Your third class
public class ThirdClass extends Dog{
//here you can instantiate Dog
private Dog dogObject = new Dog();
public void anyMethod(){
dogObject.anyMethodsThatAreDefinedInClassDogAndAnimal();
}
}
Hope this helps!!
You can extend one class and have another class as composition like this:
public class MyClass extends Dog {
private Animal animal; // instance of Animal class
// rest of the code to expose Animal class's attributes as per your need
}
Dog should be a subclass of Animal. Then your third class would be a subclass of Dog. This third class would have the attributes of Dog and Animal.
If Dog is not a subclass of Animal then you would need multiple inheritance to achieve what you want. Since Java does not support multiple inheritance you have to make Dog a subclass of Animal.
Or in case, your two classes are not in same inheritance hierarchy, then you have two options: -
Either make them interfaces, and then you can implement both the interfaces.
Or, use Composition instead of Inheritance, in which case, you would need to have the references to both the classes - Animal and Dog, as attribute in your class.
E.g: -
public class YourClass {
Animal animal;
Dog dog;
}
However, it doesn't make sense to have Animal and Dog class, with Dog not being a subclass of Animal. So, you should change that first, and then you would be able to use inheritance.

Categories