This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does it mean to “program to an interface”?
Interface vs Abstract Class (general OO)
I'm new to learn JAVA and now I'm confused about interface. I have searched and read many materials but still not clear.
When I try to find some information about interface, I see many people talked about the relationship between interface and abstract class. But I even don't know why they contrast these two. Because I think abstract class is used to tell other people you can not create an object of this abstract class and if you want, you must modify the abstract class. This is something about inheritance, right?
But I don't know the meaning of interface. There is a interface a, and if a class B is going to implement the interface a, it must use the reserved word class B implements a, and then complete all the methods that the interface requires. But my question is, if class B have to complete all the methods by itself, what's the meaning of interface? I think we don't need it.
I don't understand it very much. I read many sentences like: "interface can reflect the core thought of object-oriented language", "interface can help make the program easier" and so on. But I can not really understand the meaning.
So, does anyone can show me some examples to let understand interface? Or you can tell me some useful links or the books that describe the interface clearly. I really hope to figure it out. THANK YOU!
Suppose you have a Car class and Vegetable class which is unrelated in real life and there is a common behaviour called wash(). Because we can wash a car and wash a vegetable too. But washing a car and washing a vegetable is totally different process/behaviour.
For ex: Car should be washed with a power pump, Vegetables under your kitchen sink. So the way of washing is different. So you make the washing process as a method wash() in the interface say Washable and you implement them in both Car and Vegetable class.
interface Washable {
public void wash();
}
public class Car implements Washable {
public void wash() {
// wash the car with a power pump
}
}
public class Vegetable implements Washable {
public void wash() {
// wash the vegetable under a kitchen sink
}
}
As a person, you would want to wash a car as well as vegetable.
public class Person {
Washable washableObject = new Car();
washableObject.wash();
washableObject = new Vegetable();
washableObject.wash();
}
So interface is a way to connect unrelated classes which has a common behavior.But the behavior will be differently implemented or can be changed in future.
One day you decide to change the way you wash a Car.Suppose you have purchased a "car washing machine". So the implementation changes inside the method wash() in the Car class.
public class Car implements Washable {
public void wash() {
// wash the car with my new car washing machine !!
}
}
But as a Person , you still call the wash() method. The way the wash() method is being implemented changed ( washing the car with your new car washing machine ), this implementation change did not affect your Person class.
Hope you are clear why we use interfaces now.
Basically, interface is a way to accomplish multiple inheritance without actually having to do it. (Which is not to say that the Java folks "wimped out" -- multiple inheritance is exceedingly messy and inefficient to implement.)
What this means is that you can have two totally separate classes A and B, with no common ancestor other than Object, and, if they implement the same interface, you can substitute one for the other (so long as you reference only methods in the interface).
A simple code to understand the interface and class.
import java.util.List;
import java.util.ArrayList;
public class Q01 {
List<Shape> shapes= new ArrayList();
public void add() {
shapes.add(new Square(3.0));
shapes.add(new Circle(2.0));
}
public void print() {
for (int i = 0; i < shapes.size(); i++) {
Shape shape = shapes.get(i);
System.out.println(shape.getClass().getSimpleName() + " --->" + shape.getArea());
}
}
public static void main(String[] args) {
Q01 q01= new Q01();
q01.add();
q01.print();
}
public interface Shape {
double getArea();
}
public class Square implements Shape{
private double edge;
public Square(double edge) {
this.edge = edge;
}
public double getArea() {
return edge*edge;
}
}
public class Circle implements Shape{
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getArea() {
return 3.14 * radius * radius;
}
}
}
Think in interfaces like contracts between a class and the user. When a class implements an interface is telling that it promise to offer all the methods defined by the interface.
Assuming you understand class inheritance, I think of an Interface like a skeleton class, where the structure of a class is described but not actually written/implemented.
Another class can then work with any class that implements a particular Interface even if it hasn't been implemented yet.
For example, someone may create an Interface called Animal. Its methods maybe: Talk(), Walk() and Eat(). You could write a Dog class that implements Animal that prints "woof" when the Talk() method is called. Therefore another class will know how to work with all classes that implements the Animal interface.
UPD
A good real world example is the JDBC Database Statement Interface. This sets out a number of required properties that a database manufacturer will have to implement, such as execute(String sql). Oracle will implement this differently from Postgresql. This allow the database to be swapped for another one but the user code remains the same.
Related
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 :)
Scenarios where we can go for abstract class and where we can go for method overriding.
Let me explain.
I have a class A.
abstract class A {
abstract public void display();
}
and In usual case I can extend this class as
class B extends A {
public void display() {
System.out.println("This is a bike");
}
}
The same this I could do by using method overriding feature even if the method of the class A has something.
So my question is, when should I go for abstract class when the same feature i can achieve by method overriding.
The main point of an abstract class/method is to provide a base type for polymorphic usage. In other words, you have some base type A that others will extend to provide some operation. You do not care about the exact implementation, but you to want that operation to be available.
An often-cited example is a Shape class:
abstract class Shape {
public abstract void draw();
}
class Circle extends Shape {
int radius;
// Constructors, etc.
#Override
public void draw() {
System.out.println("Circle of radius " + radius);
}
}
class Square extends Shape {
int side;
// Constructors, etc.
#Override
public void draw() {
System.out.println("Square of side " + radius);
}
}
Class Shape is a way of referring to any shape. You know that there cannot be instances of class Shape, but you can still have a Shape[] or a List<Shape>. That way, you can use it like this:
void drawAll(Iterable<? extends Shape> shapes) {
for (final Shape s : shapes)
s.draw();
}
If you didn't have an abstract base class Shape, you would not be able to write this method; you would have to write one for a list of Circle objects and another one for a list of Square objects - and even that solution would still not allow you to do this:
List<Shape> ls = Arrays.asList(new Circle(7), new Square(5));
drawAll(ls);
An abstract class is a class that has at least one abstract method. That is a method that is not implemented in this class but has to be implemented by derived classes.
Abstract classes should be used to represent abstract concepts. You cannot create objects from abstract classes, they are only used to derive concrete classes from them.
Actually, my opinion is that abstract classes don't make sense in most cases. You should use interfaces instead.
First things first: Abstract methods eoncorporate overriding. In this sense, your question is somehwat ill-formulated.
Now to the bear in the room: In your example, you gave example classes A and B:
abstract class A {
abstract public void display();
}
class B extend A {
#Override
public void display(){
System.out.println("This is a bike");
}
}
I added the #Override annotation to furhter enforce the notion that abstraction uses overriding. If display() in A would not be absatract, you would not have any (easy) possibility to enforce that each sub-class of A has a methode display(). You could of course implement display() within A.
In some cases, though, this might not be possible since you do not have enough information to write the method in question. Take for example the get(int index) method of some list. The implementation of the getter depends heavily on the list implementation (accessing the 100th element of an ArrayList works fundamentally different than accessing the 100th element of a LinkedList). But yon know for sure that each list should always have this method. So you make this method abstract1.
To sum up: In a perfect world, where every programmer writes and reads docs, you probably would not need abstract methods. But we are all humans (i.e. we do not read every line of documentation and we make mistakes/forget things) and therefore it is good to have some protection against this mistakes. Furthermore, it is counter-intuitive to have empty methods and expect users to overwrite them for your program/library to work.
1 Sidenote: In actuality List is an interface, not a class. I used this example only for demonstration purpose.
I have had a search on SO, and found many similar questions, but none specifically relating to Java.
I am implementing a BST for a project I am working on, and I would like it to be able to use the same logic for multiple classes of objects as records.
For example, I want one BSTDriver class where I can make a binary tree be able to accept and build trees with objects of type Fruits, Vegetables, Meats, etc, so that I don't have to make one BST driver class for each type of object.
I am not new to Java, but as of now do not know how to do this.
You're still pretty new to Java and Object Oriented Programming in general. This is not a bad thing, but recognize it and you will do better.
This is a job for an Interface class. Allow me to introduce you to the topic.
An interface provides two things: A top level object which you can operate on, taking implementation for granted, and the ability to contract with the future on the minimum set of operations the classes that implement you interface will have available.
For example, consider the terms Vehicle, Bicycle, Car, and Buick. If I were to implement these as Java classes, I'd make Vehicle the interface with Bicycle and Car implementing it. Consider the following:
public interface Vehicle {
public void move();
}
public class Bicycle implements Vehicle {
int wheels;
public Bicycle {
wheels = 2;
}
#Override
public void move() {
//implementation for steering/pedaling the bike
}
}
public class Car implements Vehicle {
int wheels;
int fuelCap;
public Car {
wheels = 4;
fuelCap = 12; //12 gallon tank
}
#Override
public void move() {
//logic to drive the car
}
}
Now any method that takes a Vehicle as will take a Bicycle or a Car, but you can only guarantee it the ability to move (though not how). This gets more useful with return types, but I've left them out for brevity. Go read the tutorial on the subject.
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 am trying to understand better oop ,but I don't understand how to use abstract classes.
I have a car class, and a car can be mercedes , audi and volvo. Mercedes cars can have 5 passengers ,can open door and block windows; audi car can have 6 passengers, and just can open door. Volvo car can only have 3 passengers.
So, in order to do this, I created an interface:
public interface Car{
void openDoor();
void blockWindows();
int passengers=0;
}
then for each car I created an abstract class:
public abstract class Mercedes implements Car{
public void openDoor(){
System.out.println("Mercedes opendoor");
}
public void blockWindow(){
System.out.println("Mercedes blockwindow");
}
public Mercedes()
{
int passengers=5;
}
public abstract class Audi implements Car{
public void openDoor(){
System.out.println("Audi opendoor");
}
public Audi()
{
int passengers=6;
}
}
public abstract class Volvo implements Car{
public Volvo()
{
int passengers=6;
}
Now, I need to create an object that can transport maximum 15 cars. So I wrote:
public class TransportCars{
Car[] transport=new Car[15];}
//now I need to put in transport array differents types of cars. But I can not instantiate abstract classes. Should I use anything else? I used abstract classes because I can implement an interface and use just o part of it
Basically your design is completely wrong, as you are yet new to java, you first need to understand basic.
Design should be like this :
Car is a Vehical, so is-a relationship.
So you can create a Class Vehicle.
class Vehicle {
// properties of Vehicle like type of Vehicle, numberOfWheels etc.
String vType;
int numberOfWheels;
int passengers;
}
// Car is a Vehicle so it should extend Vehicle
class Car extends Vehicle {
String type; // sedan or hatchback
String manufacturer; // Mercedes, BMW, Audi, Volvo etc.
}
If you want to restrict Vehicle not to be instantiated, you can declare it as an abstract class
Interfaces and abstract classes have some similarities, but are not the same. For your example, you should probably make Car an abstract and have Mercedes, Audi, and Volvo extend that abstract class. Then make sure to implement any abstract methods in Car in each of your classes which extend it. Doing so will make them concrete classes, which can be instantiated.
One thing you can do with abstract classes which you cannot with interfaces, is include data. I see you're already doing that with your interface for number of passengers, but in an interface, the value will be static and final.
I see the problem why it's hard for you to understant abstraction, it's because your example is wrong. The type of car must be a concrete class which inherits from an abstract class. The specificity of an abstract class is that you can't create one of it, you can only inherit it ,that benefits polymorphism. But the real benefits comes from abstract methods.
Instead of creating a Car interface ,create a Vehicle interface.
Since you don't know how many passengers each type of car can carry make Car an abstract
class. Every vehicle have to start and stop. And you know that a car must load the passengers first in order to start. In the end you can start all your vehicles regardless what type car is it , οr what type of vehicle.
interface Vehicle {
public start();
public stop();
}
abstract class Car implements Vehicle {
protected wheels = 4;
public start() {
loadPassengers();
// do extra stuff like
//closeDoors();
}
abstract public loadPassengers();
}
public class Volvo extends Car {
int passengers = 6;
public loadPassengers() {
doSomething(this.passengers);
}
}
public static void main() {
List<Car> cars = new ArrayList<Car>();
cars.add(new Volvo());
cars.add(new Mercedes());
for(Car car : cars) {
car.start();
}
}
In terms of relationships between classes, there's notmuch differences between abstract classes and interfaces: You can't instantiate any of them and they would be used as a template for objects depending on them. You can implement partially the methods of an abstract class however, but even if all of them are implemented still you can't instantiate a class defined as abstract. To be concise:
Interfaces:
Define methods.
A class can implement several interfaces.
Public visibility (or package, by default).
Can't be instantiated.
Abstract classes:
Define methods and may implement them.
A class can inherit from only one class (abstract or not).
User defined visibility.
Can't be instantiated.
If your cars are meant to implement several interfaces, use interfaces, but their scope will have to be public or package. If you just want to have an inheritance relation with one class, use abstract.
It seems that you are going about this the wrong way. It would be better for you to seek a tutorial, but I will try to clear up as much as I can for you:
The car class should be either an interface or an abstract class (or neither).
If it's an interface, than Mercedes, Audi and Volvo should implement it.
If that is the case, any method in "car" must be implemented in the others, so all of them must have "Open door" and "Block windows". you must choose for each of the implementing classes how it will implement it.
If it's an abstract class, you can have some of the methods implemented in "car" and they will work "as is" in Mercedes, Audi and Volvo (which will "extend" car), unless you re-define them in their respective classes. if you want to enforce their implementation in each of inheriting classes, you can define those methods to be abstract in "car", and not implement them in car at all.
If you want to implement all of the methods in car, you don't need it to be abstract at all. You could still re-define them as mentioned above.