The purpose of this Java code - Object Creation - java

I would like to understand the following code. Is there a name for creating an object with two classes? I assumed I would create a Deer object that can call methods/variables from the Animal class but it does not seem to be working. Why would someone want to create an object like this in Java?
public class Animal {
int J = 20;
}
public class Deer extends Animal {
int Q = 40;
}
public void test() {
Animal D = new Deer();
}

This is called inheritance, which is extremely useful when you're doing anything OOP-related in Java.
You currently don't even have any methods in either class so you can't test how methods would work right now. However, if you added a method in the animal class (e.g. public void talk() {}), you could call that method in the Deer class using super.talk().
As a side note, if you're declaring a class as public, it needs to be in its own separate file or you'll get a compiler error. If you want everything to be in one file, just take out the word public.
You can visit https://www.w3schools.com/java/java_inheritance.asp for more information on inheritance and classes.

First of all I found the question description is too short. So try correcting it.
This type of class creation is part of something called as inheritance it helps when
we don't want to provide access of the function of a subclass.(So our base class act as a wrapper.)
To override the function of baseclass. So that when baseclass function is called, it behaves as if the subclass function has been called.
lets take example
public class MyClass {
public static void main(String args[]) {
Animal D = new Deer();
System.out.println(D.getType());
}
public static class Animal{
String Type="Animal";
public String getType(){
return Type;
}
}
public static class Deer extends Animal{
String SubType="Mammal";
public String getType(){
return SubType;
}
public String eatgrass(){
return "eatgrass";
}
}
public static class Bird extends Animal{
String SubType="bird";
public String getType(){
return SubType;
}
public String fly(){
return "flying";
}
}
}
In the above example.
We can see that not all animals eatgrass, so we would like to hide that detail and only use the function that are common to all animal objects, Here in this case its getType()
We want the D.getType() to return the closest type of class name of deer in animal chart which is "mammal". So when we call D.getType() instead of getting "Animal" as what you would be expecting looking at the code, we will be getting "Mammal"

This can be helpful when you need to re-use code and get information from both classes, For example, class ANIMAL and subclasses Dog, Cat, Monkey, and so on.
In the end, all of them are animals with similar methods like eating, run, sleep but in a deeper way each one of them has unique behaviors, the cat can eat but it also can meow, the Dog can run but it also can bark.
so they have unique and similar actions to perform.
inheritance is a good way to re-use an existing code from the parent class.
you can check inheritance docs.
Inheritance

Related

Abstraction and Data Hiding in java

I'm trying to understand the concept of abstraction in java. When I came through some tutorials they said that Abstraction is a process where you show only “relevant” data and “hide” unnecessary details of an object from the user.
This is a simple example of how abstract classes are working.
public class Demo {
public static void main(String[] args) {
Animal a = new Dog();
a.sound();
}
}
abstract class Animal {
abstract void sound();
}
class Dog extends Animal {
#Override
public void sound() {
System.out.println("woof");
}
}
I understand that though abstract classes we can implement common methods in sub classes like sound() method.
What I don't understand is how that help with data hiding and viewing necessary data only.
Please explain this concept to me.
If you have good example please include that too.
In your example, you create a Dog and then use it as an animal. In this case, the abstraction is not very useful, because you know that the variable a always refers to a dog.
Now let's say that in some other class you have a method soundTwice:
class OutsideWorld {
static void soundTwice(Animal a) {
a.sound();
a.sound();
}
}
Here you don't know what kind of Animal a refers to, but you can still sound twice.
UPDATE
I'm adding this class because the class Demo doesn't hide much: it needs to know about class Dog because it creates an instance of it. class OutsideWorld on the other hand doesn't: it only knows about class Animal and what class Animal exposes. It doesn't even know that class Dog exists.
we can now write a class Cat with a different implementation of method sound ("meow"), and we can still use the same soundTwice method with a Cat.
We could then rewrite the Demo class:
public class Demo {
public static void main(String[] args) {
Animal a = new Dog();
OutsideWorld.soundTwice(a);
a = new Cat();
OutsideWorld.soundTwice(a);
}
}
That would, of course, produce the output:
woof
woof
meow
meow
Abstraction in Java is not different then what we use in Software engineering terms.
Abstraction generally answers to WHAT part of your problem statement.
What all operations a system will support?
What is the system meant for?
Think about the abstract datatypes:
Example Stack
All you care about is
pop() --> return you the top element
push() --> adds the element
You simply don't care about the implementation details. So your java classes are abstracted in the same way.
Abstraction is not just about showing only “relevant” data and “hide” unnecessary details of an object from the user.
Data Abstraction is the property by virtue of which only the essential details are displayed to the user.The trivial or the non-essentials units are not displayed to the user. Ex: A car is viewed as a car rather than its individual components.
In java, abstraction is achieved by interfaces and abstract classes. We can achieve 100% abstraction using interfaces.
The one you are explaining in your example is one just form of it.
In your example of Animal class, if sound() method is not an abstract one and you have some random abstract method in that class, imagine a case someone wrote the Animal class and you are extending it in Dog class. Irrespective of the implementation in Actual Animal class, you can write the code in your current class.
Imagine the you haven't overriden the sound() method in Dog class, still if you call `
Dog d= new Dog(); d.sound();
` will get you the code of Animal sound().[Given: sound() method is not abstract]. The code of Animal class would be executed. Dog object does not even know what the sound() method has in it...but it is still able to make use of it. This process of not knowing but making use of something is what abstraction actually is
As mentioned by Yati Sawhney, pop() and push() methods are quite good examples.
Else,
you can have hascode() and equals() method from Object class,
where no one knows how the calculation is done but you end up with a
number and comparing the references respectively.
Data Hiding/Encapsulation:
Data hiding is not same as Abstraction. Not to confuse one with the other.
Abstraction is hiding the code implementation from other Object/user
whereas Data hiding is achieved by Encapsulation via POJO classes.
Data hiding has to do with the instance variables which decides the
state of the Object. Hiding its content using the setter() and
Getter() methods is Data Hiding/ Encapsulation.
You may wonder, how a getter() method is hiding the data whereas it just returns the data we requested but there is an untold story about the getter/setter methods.
Example: Refer the getName() method from the below code
public class Person {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
// can restrict the code without displaying data to user
if(condition)//restricted user check
return null;//returning null because the user is not supposed to view the data
return name;
}
}
Abstraction means - not providing/having the implementation details. Imagine you are the authority to decide on what parts a Car must have. You will list those functionalities as abstract methods.
Later you will share this (contract) abstract template to Hundai, Ford etc to have their own implementation to make a complete Car.
Abstraction
Ways to achieve Abstraction
There are two ways to achieve abstraction in java
Abstract class (0 to 100%)
Interface (100%)
Basic Knowledge about :
Abstract Methods and Classes
An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
public abstract class ClassName{
// declare fields
// declare nonabstract methods
abstract void methodName();
}
When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract.
An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:
abstract void methodName(Parameter List);
Abstraction is a process of hiding the implementation details and showing only functionality to the user.
Understanding the real scenario of abstract class:
Consider a situation of making a function to get student strength of any school.
Now we will create an abstract class and abstract function getStrength().
Then every school (Govt or private) can use this abstract method and provide implementation.
//Consider this Code
package stackoverflow;
abstract class StudentStrength {
abstract int getStrength();
}
class GovtSchool extends StudentStrength {
#Override
int getStrength() {
return 100;
}
}
class PrivateSchool extends StudentStrength {
#Override
int getStrength() {
return 200;
}
}
public class GetInfo {
public static void main(String args[]) {
StudentStrength ss;
// referring abstract class and creating object of child class
ss = new GovtSchool();
System.out.println("Student strength in Govt School : "+ ss.getStrength());
// output of above : 100
ss = new PrivateSchool();
System.out.println("Student strength in Private School : "+ ss.getStrength());
// output of above : 200
}
}
Explanation:
In this example, StudentStrength is the abstract class, its implementation is provided by the GovtSchool and PrivateSchool classes.
Mostly, we don't know about the implementation class (i.e. hidden to the end user) and object of the implementation class is provided by the factory method.
In this example, if you create the instance of GovtSchool class, getStrength() method of GovtSchool class will be invoked.
File: GetInfo.java
Student strength in Govt School : 100
Student strength in Private School : 200
ANSWER TO:
What I don't understand is how that help with data hiding and viewing necessary data only.
Like demonstrated in the above code, we are referring the abstract class and using the functionality of the child class hiding the working of child class from the end user.
I hope I was helpful :)

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.

Practical example Encapsulation vs Information Hiding vs Abstraction vs Data Hiding in Java

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.

Play Framework 2.1.0 not seeing static method from derived class

I'm using Play Framework 2.1.0 with Java, and I came across a strange error that I don't quite understand.
I have a base class in the package models.entities Animal.java that defines a public static method List<AnimalType> getAllCows(), as shown below:
package models.entities;
public class Animal {
public static List<Cow> getAllCows() {}
}
I then have a class that extends Animal:
package models;
public class Cow extends Animal {
}
From my Scala template show_animals.scala.html, I am able to call the following:
models.entities.Animal.getAllCows()
But when I try to call the static method using the extending class, it errors as follows:
Cow.getAllCows()
value getAllCows is not a member of object models.Cows
It seems to me that it should work, but it does not... Am I missing something?
Thanks!
A static method only belongs to the class that declares it. Since, it's only the Animal class that has defined it, Cow.getAllCows() throws an error. You can think of it as a global method that's accessed through a namespace (its class name). The way an instance method gets inherited (with polymorphism) does not apply to static methods.
The concept is a bit difficult to grasp because if you were to write the Cow class as below it would work.
public class Cow extends Animal {
public static List<Cow> getCows() {
return getAllCows(); // inherited; or some prefer visible
}
}
So, if you change your code to
public class Animal {
public static List<Cow> getAllCows() {
System.out.println("Animal.getAllCows() invoked");
}
}
public class Cow extends Animal {
public static List<Cow> getAllCows() {
System.out.println("Cow.getAllCows() invoked");
return Animal.getAllCows();
}
}
Cow.getAllCows() would work re-using the base class implementation.
However, note that this wouldn't give you polymorphism. You've simply re-implemented the method (of the base class) also known as method-hiding. So, if you were to run the following
Animal animal = new Cow();
animal.getAllCows(); // would print: Animal.getAllCows() invoked

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