I have this interface:
public interface Animal {
void Eat(String name);
}
And this code here implements the interface:
public class Dog implements Animal {
public void Eat(String food_name) {
System.out.printf(food_name);
}
public static void main(String args[]) {
Animal baby2 = new Dog(); // <- this line
baby2.Eat("Meat");
}
}
My question is, why does the code work? An interface cannot be instantiated. Yet in this case, interface was instantiated (marked with the comment).
What is happening here?
No it is not - you are instantiating a Dog, but since a Dog is an Animal, you can declare the variable to be an Animal. If you try to instantiate the interface Animal it would be:
Animal baby2 = new Animal();
Try that, and watch the compiler scream in horror :)
Dog is not an interface: Dog is a class that implements the Animal interface.
There's nothing untoward going on here.
Note that you can instantiate an anonymous implementation of an interface, like so:
Animal animal = new Animal() {
public void Eat(String food_name) {
System.out.printf("Someone ate " + food_name);
}
};
Let's consider below code:
interface Cookable {
public void cook();
}
class Food {
Cookable c = new Cookable() {
public void cook() {
System.out.println("anonymous cookable implementer");
}
};
}
The preceding code creates an instance of an anonymous inner class, but here, the new just-in-time class is an implementer of the Cookable interface. And note that this is the only time you will ever see the syntax:
new Cookable()
where Cookable is an interface rather than a nonabstract class type. Think about it:
You can't instantiate an interface, yet that's what the code looks like it's doing. But, of course, it's not instantiating a Cookable object-- it's creating an instance of a new anonymous implementer of Cookable.
You can read this line:
Cookable c = new Cookable(){}
as "Declare a reference variable of type Cookable that, obviously, will refer to an object from a class
that implements the Cookable interface. But, oh yes, we don't yet have
a class that implements Cookable, so we're going to make one right
here, right now. We don't need a name for the class, but it will be a
class that implements Cookable, and this curly brace starts the
definition of the new implementing class."
Important to remember for anonymous interface implementers-- they can implement only one interface. There simply isn't any mechanism to say that your anonymous inner class is going to implement multiple interfaces. In fact, an anonymous inner class can't even extend a class and implement an interface at the same time. The innve class has to choose either to be a subclass of a named class and not directly implement any interface at all or to implement a single interface.
So don't be fooled by any attempts to instantiate an interface except in the case of an anonymous inner class. The following is not legal:
Runnable r = new Runnable(); // can't instantiate interface
whereas the following is legal, because it's instantiating an implementer of the Runnable interface(an anonymous implementation class):
Runnable r = new Runnable() {
public void run(){ }
};
You can read my article here.
What you're observing here is the Dependency inversion aspect of SOLID.
Your code is depending on the abstraction of the Animal contract by instantiating a concrete implementation of it. You're merely stating, "I'm instantating some object, but regardless of what that object actually is, it will be bound to the contract of the Animal interface."
Take, for instance, these sorts of declarations:
List<String> wordList = new LinkedList<>();
Map<Integer, String> mapping = new HashMap<>();
In both of those cases, the primary aspect of the list and map is that they follow the generic contract for a List and Map.
Animal baby2 = new Dog(); //HERE!!!!!!!!!!!!!!!!!!!!!!
Surely you are not instantiating the Animal. You are only referring the Dog instance to it.
In java we can take the super class reference.
This is a case of polymorphism, It looks like you are creating 'Animal' object but it is not. You are creating 'Dog' object which is calculated on run time.'Animal' acts as contract. Interface can not be instantiated directly but can be used as type by upcasting its subclass. You can also use anonymous class to instantiate an object as 'Animal' type.
Animal baby2 = new Dog(); //upcasting polymorphically
Animal baby3=new Animal(){
public void Eat(String food){System.out.println("fdkfdfk"); }
}
//You can instantiate directly as anonymous class by implementing all the method of interface
The interface Animal is not be intantiated but be implemented by Dog.And a Dog is intantiated
When you say:
Animal baby2 = new Dog();
the reference type is Animal(the interface) which points to a concrete implementations (Dog). The object type Dog is concrete and can be instantiated. In this case, as long as Dog hasanimal point to Dog. a concrete implementation of all the methods in the interface, you can make a reference type of
If you did something like,
Animal baby2 = new Animal(); // here you are actually instantiating
this would be invalid because now you are trying to create a concrete object from an abstract implementation.
The Interface Animal acts as the data type to the class Dog. You're actually instantiating the Dog class not the interface or it's data type.
To have a wider picture :
Animal [] Zoo = new Animal[10] ; // is also correct
but why ?
The whole idea is that in the table above you can put 10 animals of different types. The only conditions for this is that all the animals entering the Zoo must implement the interface Animal .
public interface Animal {
void Eat();
}
class Wolf implements Animal { void Eat (){
System.out.println("Wolf eats meat ") ;}}
Class Zebra implements Animal{ void Eat (){
System.out.println("Zebra eats the grass ") ;}}
class test {
public static void main (String args []) {
Animal [] Zoo = new Animal[2] ;
Zoo[0] = new Wolf() ;
Zoo[1] = new Zebra() ;
//so you can feed your animals in Zoo like this
for (int i=0 ; i<Zoo.lenght;i++) {Zoo[i].Eat();}
}
}
You can't instantiate an interface. The functionality can be considered similar to that of an abstract class. You can have a reference to the interface but you don't create an object of interface. If you do something like this....
Animal a = new Animal();
The compiler will show an error- "Cannnot instantiate the type Animal".
Actually you can instantiate the interface. Here is the code you can try
public static void main(String args[]) {
System.out.println(new Animal() {
public String toString() {
return "test";
}
});
}
This program runs successfully and prints test
Try it.
Here it is just referencing to the interface but instantiation is done by the class only.
for e.g
Animanl a = new Dog
Animal a - variable is referenced
new Dog - now Memory is allocated
Java 8 let you use, the functional interface,
#FunctionalInterface // this is not mandatory
interface A{
void m1(); // only one abstract method allowed for functional interface
}
class Main{
public static void main(String a[]){
// old usage
A a1 = new A(){
#Override
public void m1(){
System.out.println("Call Me normally");
}
};
a1.m1();
// new in java 8, functional interface
A a2 = ()-> System.out.println("Call Me as functional interface");
a2.m1();
}
}
What have you done is type casting. You have created an instance of class dog and has type caste it to interface animal.It is an example of runtime polymorphosim. But yes an interface can be implemented and I have reached here while searching for this.
i.e.
public class demo16{
interface cardio{
void run();
}
static void foo(){
cardio c = new cardio(){ //HENCE instance of "interface cardio" is being created inside a method foo
public void run(){
System.out.println("How you doing ! ");
}; //HENCE observe the ";" beside }
}; //HENCE observe the ";" beside }
c.run();
}
public static void main(String [] args){
foo();
}
}
Related
I mean if we want to rewrite all the content of the method in the child class and change its function, why couldn't we just write a new method with a different name? What's the difference? I know this is a simple question. But I am new to programming and very confused. THX.
It's about giving different behaviour to common functionality for that type of thing, for example let's assume all Vehicles beep, but a Car Honk's and a Moped Meep Meeps!
class Vehicle {
public void beep() {
System.out.println("Beep!");
}
}
class Car extends Vehicle {
#Override
public void beep() {
System.out.println("Honk!");
}
}
class Moped extends Vehicle {
#Override
public void beep() {
System.out.println("Meep Meep!");
}
}
That's called Polymorphism. Have a look at the link.
A simple example is the Java Collections framework. You have an interface List when you are using it. You don't want to know how add or size is working. It should just work.
But when you are on the implementation side there are differences for ArrayList or a LinkedList in the way how they manage the items, that where stored in there.
When you look at already implemented methods in super classes, you might need one method to have a different behavior. Now pretend you have some method calls in your current code. If you don't want them to change, so you just override that method and the client does not have to change his code in order to use your functionality.
Overriding is a feature that is available while using Inheritance.
It is used when a class that extends from another class wants to use most of the feature of the parent class and wants to implement specific functionality in certain cases.
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
System.out.println("Dogs can walk and run");
}
}
class Cat extends Animal{
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
Animal c = new Cat(); // Animal reference but Cat object
a.move();// runs the method in Animal class
b.move();//Runs the method in Dog class
c.move();//Runs the method super method
}
}
So by using a parent class you dont need to define move() in each of class that extends animal you can override it wherever necessary.
I've read a few questions about instantiating an interface, but either none of them addressed my question, or else I didn't fully understand what was happening.
Observer observer = (Observer) observers.elementAt(i);
I've never encountered a statement like this. Looks like a weird way of instantiating an object. However, Observer is an interface, and the class that this statement is made in (class is abstract, if that has any bearing) doesn't implement the interface.
Could anyone explain to me what exactly is happening?
The statement is retrieving an object from some sort of collection. The object is explicitly cast to the type Observer and assigned to observer variable. The object is not being instantiated, just retrieved. The explicit cast makes this statement slightly dangerous because there is no way to guarantee the object retrieved from the collection implements Observer.
First of all, it doesn't instantiate anything, it just grabs an instance of some implementation of Observer from a collection (I assume it's Vector by the method name).
So this is what's going on
Vector observers = new Vector();
observers.add(new ObserverImpl());
Observer o = (Observer) observers.elementAt(0);
Note that this a very oldschool way of doing things, you shouldn't use Vector anymore and you should always use generics, so this code should be rewritten as
List<Observer> observers = new ArrayList<>();
observers.add(new ObserverImpl());
Observer o = observers.get(0); //you don't need to cast anymore because of generics
An interface is a type of contract that ensures that the methods defined on that interface is implemented. If an object implements an interface it has to have to cater for all the methods defined on it.
In your code example an object is cast to a variable of type Observer which means you can call any of the Observer methods. It does not change the object, nor is it instantiated.
First of all, an abstract class is a class who can't be instantiated, sometimes there is only one method abstract, sometimes the whole class is abstract. You'll have to extend such a class. It allows you to implement functionality in a base class.
An interface is a contract for a class and is implemented by the keyword implements. It Provides you the method calls, there is no functionallity in interfaces.
Now to your question:
Observer observer = (Observer) observers.elementAt(i);
This ensures an object ( containing methods like: equals, hashCode or toString) has the methods of an interface.
ex in pseudocode:
interface Printable{
String print();
}
and its "implementation":
public class MyDocument implements Printable{
#Override
public String print(){
// do the print thing
}
public void additionalMethod(){
// do some other stuff
}
}
and its use
Printable doc = new MyDocument(); // now we ensure that we can call .print()
An interface is a contract to its implementing classes. It is perfectly legal to write a code that you encountered .
Lets understand this with a simple example :
create an interface Animal
public interface Animal {
public void eat();
}
create two implementing classes as Horse and Cat that implements this interface.
public class Cat implements Animal {
public void eat() {
System.out.println("Cat eats Mouse.");
}
}
public class Horse implements Animal {
public void eat() {
System.out.println("Horse eats hay.");
}
}
Now test the behavior using a Tesy class :
public class Test {
public static void main(String[] args) {
Horse h = new Horse();
Cat c = new Cat();
Animal a = (Animal)h;
a.eat();
a = (Animal)c;
a.eat();
}
}
The output would be :
Horse eats hay.
Cat eats Mouse.
This kind of behavior supports dynamic polymorphism or run time polymorphism.
Even though you have the reference of Animal object you hold the objects of Horse or Cat which implements the methods so you can call them. An Animal reference holding the object of class that implements it can call only those methods which are declared in the interface Animal.
For example: Foo ab=new Dog();
Saving object of another type class to reference of another class!
It's not always necessary to do something like Foo foo = new Bar() but it's often recommendable to refer to the interface and not the implementation.
This way you can change your implementation without needing to change other code.
For example if you're doing something with Lists and you use ArrayLists you might do:
ArrayList<Integer> numbers = new ArrayList<>();
//Do stuff with numbers
However you might not care what kind of list it is so you're probably better off with
List<Integer> numbers = new ArrayList<>();
//Do stuff with numbers
Now it doesn't matter what kind of List you've got and maybe you find that you'll get better performance with a LinkedList and you can just use that instead of changing any other code.
I would say that polymorphism is most important when receiving objects by other callers though.
Yes if Foo is an interface then this approach gives you more control on your code. You achieve Polymorphism, Plug-ability, Maintainability and Loose coupling characteristics of java programming language.
Let's say if you are supposed to connect to oracle from your application and written the code like this
OracleDrive driver= new OracleDriver()
driver.connect();
it will solve your problem. But will make your code tightly coupled with OracleDriver. Your application won't compile at all if you remove Oracle related jar from your classpath. And if someone ask you make your app connect to different DBs based on their configuration then you end up with multiple ifs based on your application supported DBs. which is bad practice as per programming standards.
If you all DB drives implements an interface Driver then you can load driver based on configuration without tightly coupling your code to any specific driver class like this
Driver driver = properties.get(db.driver.class)
driver.connect()
Now you see that you need to change you application to connect to MySql you just need to set that class in your configuration file.
Hope you got my point!
It's more useful with method parameters.
class Animal {
public boolean hasHair = true;
public void speak() {}
}
class Dog extends Animal {
public void speak() {
System.out.println("Woof!");
}
}
class Person {
public void shave(Animal a) {
a.hasHair = false;
a.speak();
}
}
class Main {
public static void main(String[] args) {
Person joe = new Person();
Dog fido = new Dog();
joe.shave(fido);
}
}
In this case a Person can shave any Animal, but we pass it a Dog.
Animal fido = new Dog(); would be less useful, because we know fido is a dog, but consider this:
Animal pet;
if(joe.prefersCats)
pet = new Cat();
else
pet = new Dog();
Simple answer, You cannot do that.
More Complicated Answer, You would be able to do that only if 'Dog' is type of 'Foo'.
When will we say Dog is type of 'Foo' is if Dog implements Foo (If an interface) or extends Foo (If another Class or Abstract Class)
Now, coming to advantages of Coding to Interfaces (Technical name of your question) is
1) Java's Polymorphism is based on this (Polymorphism makes runtime change in behaviour possible, Please google polymorphism in java for more information)
2) You are making interfaces independent of implementations by this approach.
hope this answered your question.
This type of declaration is only possible
Foo ab=new Dog();
if Dog class extends class Foo or Foo is an interface which is implemented by Dog class as
class Dog extends Foo { .... }
or
class Dog implements Foo { ... } //Here Foo is an interface
I think so there is no use if you initialize class objects with inherited interface or inherited class as all the base class functions, properties will be available in your derived class object. This type of declaration will come handy if you are initializing multiple objects having same base class with different derived classes.
For Example,
public class MyObject
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class MyFile extends MyObject
{
private String extension;
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
}
public class MyFolder extends MyObject
{
}
If you are initializing
MyObject file = new MyFile();
This is really of no use but it will be useful when we want to initialize
List<MyObject> listOfFilesFolders = new ArrayList<MyObject>();
listOfFilesFolders.add(new MyFile());
listOfFilesFolders.add(new MyFolder());
This 'listOfFilesFolders' can be private variable of another class which keeps list of files/folders present.
Or we want to have function as
private void SomeFunction(MyObject obj)
{
}
which can take all the objects which are derived from base class and perform operation according to base class properties or functions.
See one of my old answers here:
What is the advantage of using interfaces
It's an anecdote about an anecdote that one of my professors once told us.
Long story short, when you get into more complex systems, the reason that you would want this becomes more clear. The ability to separate specification (interface/abstract class and its contract) from implementation (concrete class) is a powerful tool that makes it very easy to write new implementations without having to change code elsewhere in your application. You use the specification in your code, e.g. the specification:
public interface Animal { ... }
Your implementation:
public class Dog implements Animal { ... }
Then in code, you use the specification whenever possible:
Animal a = new Dog();
a.eat(); // All animals eat, so eat() is on the Animal interface
Unless you absolutely need to use the implementation itself:
Dog d = new Dog();
d.bark(); // Other animals don't bark, so we need to have the Dog here
This makes your code cleaner. For example, say I have a method feedAndGroom. If I didn't have an interface, I would need to create a new method for each animal I want to support:
public static void feedAndGroom(Cat c) { ... }
public static void feedAndGroom(Dog d) { ... }
public static void feedAndGroom(Turtle t) { ... }
Each code block might even look exactly the same, depending on the situation. Even worse, what happens when someone discovers a new animal? We'd have to add a new method each time, which would result in a huge number of methods. The solution to all this duplication is to create an interface around the functionality, then have a single method:
public static void feedAndGroom(Animal a) { ... }
This will take anything that implements the Animal interface. All these method calls are legal:
feedAndGroom(new Cat());
feedAndGroom(new Dog());
feedAndGroom(new Turtle());
However, these method calls are legal too:
feedAndGroom(new Hyena());
feedAndGroom(new Lion());
feedAndGroom(new Panther());
We may not want to try and feed and groom these animals, at least not wild ones, so we can add a new interface called DomesticatedAnimal that extends Animal:
public interface `DomesticatedAnimal` extends `Animal` { ... }
And change our method to:
public static void feedAndGroom(DomesticatedAnimal da) { ... }
Then instead of implementing Animal, the Dog, Cat, and Turtle classes will implement DomesticatedAnimal. For example:
public class Dog implements DomesticatedAnimal { ... }
This means that Dog is both a DomesticatedAnimal because it directly implements it, and an Animal by inheritance since DomesticatedAnimal extends Animal. The other animals, Hyena, Lion, and Panther, just implement the Animal interface. This means that our new method won't take just any Animal like our original one, but instead restricts it down to a specific kind of Animal object. Meanwhile, any methods written to use the original Animal interface would still work for all the objects involved.
You can always substitute a reference to a subclass in place of a base class.
In other words, you can always use something more specific in place of something more general—so if you have got a line of code that asks for a Canine, you can send it a reference to a Dog.
So this line of code:
Foo ab=new Dog();
means that you are instantiating a new Dog object, and then creating a
Foo reference called ab and pointing it at that object.
I'm kind of stuck on the following question:
What two Java language mechanisms allow the type of an object reference variable to be "different" than the type of the object to which it refers? Give specific examples to illustrate. In what sense are they not different at all?
My current answer is that it is "implement" and "extend" right? And they are similar because they both will make a class that at least will posses all of the method signatures of the super class which can be actual, abstract, or an interface. Is this correct? Thanks in advance!
That is more or less correct. The second part of your answer should talk about subtyping. In Java, it is not sufficient for objects to just have the same method signatures. There actually has to be a declared subtyping relationship (via extends / implements).
This is not mere pedantry. In some languages (but not Java), the mere existence of compatible method signatures is sufficient for type compatibility. This is called "duck typing".
Implements
interface Animal {
void attackHuman(); // actually public abstract by default
}
class Horse implements Animal {
public void attackHuman() { }; // must implement
}
// type and reference the same
Horse a1 = new Horse();
// type and reference different
Animal a2 = a1;
Extends
class Animal {
void attackHuman();
}
class Dinosaur extends Animal {
// attackHuman() inherited
}
// type and reference the same
Dinosaur a1 = new Dinosaur();
// type and reference different
Animal a2 = a1;
See this example....
- Here the Animal is the Super-Class, and the Dog and Cat are inherited out of it.
- You can Create a Dog object using an Animal Object Reference Variable.
- This is known as Class Polymorphism.
public class Test {
public static void main(String[] args){
Animal a = new Dog();
new Hospital().treatAnimal(a);
}
}
class Animal {
public void sayIt(){
}
}
class Dog extends Animal{
public void sayIt(){
System.out.println("I am Dog");
}
}
class Cat extends Animal{
public void sayIt(){
System.out.println("I am Cat");
}
}
See the NEXT PAGE for the Remaining Code
class Hospital{
public void treatAnimal(Animal a){
if(a instanceof Dog){
a.sayIt(); // Will output "I am Dog"
}
else{
a.sayIt(); // Will output "I am Cat"
}
}
}
While coding, I got an interesting doubt about polymorphism and I couldn't understand a solution for this.
public class Animal {
public void getLegs() {
SOP("4 legs");
}
}
public class Kangaroo extends Animal {
public void getLegs() {
SOP("2 legs");
}
public static void main(String[] args) {
Animal a = new Kangaroo(); // without changing this how can I get Animal getLegs
SOP(a.getLegs()); // Important Line
}
}
Now If I want to call the getLegs method of Animal, how do I? Is it possible? Is it still polymorphism?
Yes, it is the most basic form of demonstrating polymorphisim.
Basically you are dealing with an Animal named a. When you call a.getLegs() your code doesn't bind to the implementation of getLegs() in Animal, rather it binds to the lowest sub-class implementation, getLegs() in Kangraoo().
If the Animal has an implementation, it is said to be hidden by the subclass implementation. If Animal has no implementation, then it is not possible to construct stand-alone classes of Animal as they lack implementations for all of the required methods, and under such a circumstance, Animal is said to be an abstract class (one that cannot be constructed directly, but only can be constructed by it's sub classes).
If you really want to call your method for Animal, and you can employ a static method, you can use hiding instead of overriding.
It works as follows: for static methods only, the called method is the one related to the declared type, not the object instance. In other words, it follows the class because the method is a class method, not an instance method.
An example, adapted from this page:
public class Animal {
public static void testClassMethod() {
System.out.println("The class" + " method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance " + " method in Animal.");
}
}
public class Kangaroo extends Animal {
public static void testClassMethod() {
System.out.println("The class method" + " in Kangaroo.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Kangaroo.");
}
public static void main(String[] args) {
Kangaroo myRoo = new Kangaroo();
Animal myAnimal = myRoo;
myRoo.testInstanceMethod();
myAnimal.testInstanceMethod();
Kangaroo.testClassMethod();
Animal.testClassMethod();
}
}
The result will be (pay attention to the 3rd and 4th lines, as opposed to the 1st and 2nd):
The instance method in Kangaroo.
The instance method in Kangaroo.
The class method in Kangaroo.
The class method in Animal.
In Java it's not possible to access Animal's implementation. It will always return Kangaroo's version.
(Note in C# it is possible by tagging the overriding method with "new", but it's a fairly specialised use case).
Accessing what appears to be an Animal but getting the behaviour specified by Kangaroo is exactly what polymorphism is - the ability for a child object to be substituted wherever its parent is expected.
In general you wouldn't want to have the calling code know about the inheritance hierarchy because this would tightly couple your code together. If you genuinely need to access Animal's implementation of this method it suggests your design is probably wrong.
The spirit of Polymorphism is to execute different code decided at runtime. To make it more clear, I'll modify your code a bit.
public class Animal {
public void getLegs(){
SOP('4 legs');
}
}
public class Kangaroo extends Animal{
public void getLegs(){
SOP('2 legs');
}
public static void main(String[] args){
Animal a = new Kangaroo(); //without changing this how can I get Animal getLegs
Kangaroo kng= new Kangaroo ();
Animal an = new Animal();
SOP(a.getLegs()); // Kangaroo's version is called
SOP(kng.getLegs()); //Again, Kangaroo's version is called
SOP(an.getLegs()); //Animal version is called
}
}
and Yes, as all say you can't call Animal from your line Animal a = new Kangaroo();..as none will want to do it. Rather he will directly write. Animal a = new Animal();..
So finally it is the object not referance which decides which method will be called
Now If I want to call the getLegs method of Animal, how do I? Is it possible?
If you want to access the overridden method - which contradicts polymorphism - you can use reflection. Get the getLegs method from Animal's class, and then invoke it on your Kangaroo object. However, this is a hack, and not something you'd do in a regular program.
SOP( Animal.class.getMethod("getLegs").invoke(a) );