I have a class with name 'A'. A is an abstract class. And class 'B' extends class 'A'.
And I have another class 'C'. In class 'C' there's a function with name show().
I want to pass an object of class 'A' which is abstract. Is it
possible?
Or
Can we do this using Polymorphism.
If yes! then How?
I want to pass an object of class 'A' which is abstract. Is it possible?
Yes, it is. The following is valid:
abstract class A {}
class B extends A {}
class C {
public void show(A a) {}
}
Even though A is abstract, you can receive parameters of type A (which, in this case, would be objects of type B).
You cannot really pass an object of class A, though, since A is abstract and cannot be instantiated.
Can we do this using Polymorphism.
The above example actually already used polymorphism (subtyping).
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
Pretty much the same as above answer, just elaborated with code. Naive way of telling, you cannot have abstract class name next to new operator except in case with array, as in A a[] = new A[10]; where you have still allocate Objects of concrete class for each element in Array.
abstract class A{
abstract void tell();
}
class B extends A{
void tell(){
System.out.println("I am B Telling");
}
}
public class Test{
public static void whoTold(A a)
{
a.tell();
}
public static void main(String[] args){
B b = new B();
whoTold(b);
}
}
Time-appropriate greetings :)
Working in Java, I have an Interface A. All implementors of this Interface also extend class B, but B does not implement A. In a class where we use an instance of A (referenced as A), it is cast to a B Reference so that we can use a Method defined in class B. It makes sense conceptually that the Method should belong in Interface A too.
Can you think of a reason not to introduce the Method to Interface A, so that we don't have to cast it to B? Should I maybe override the Method in the subclasses and just call the super version, so that it's easier to navigate in the IDE etc?
In a class where we use an instance of A (referenced as A), it is cast to a B Reference so that we can use a Method defined in class B.
So I'm assuming you have this scenario
public void doStuff(A aType){
...
B bType = (B) aType;
...
}
If this is true, can this work?
private <T extends B & A> void example(T type){
type.aStuff();
type.doBStuff();
}
I created the following to test this.
public class Foo{
private static interface A{
void aStuff();
}
private static class B{
public void doBStuff(){
System.out.println("B stuff");
}
}
private static class AB extends B implements A{
public void aStuff(){
System.out.println("A stuff");
}
}
public static void main(String[] args) {
Foo foo = new Foo();
foo.example(new AB());
}
// method "example" already given
}
Gave me
A stuff
B stuff
Why not creating an abstract class which extends B and implements A? Assuming this class would be called C, your other classes would extend C and implement the method required by A, but will provide you with the methods available in B without casting.
I think that moving methods now would not be a good idea, maybe, at most, have B implement A (assuming you have no other classes which you haven't talked about which are dependent on the classes and interfaces you mentioned).
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 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();
}
}
Lets say class C and D extend class B which extends class A
I have a methods in class E that I want to be able to use either an object C or object D in. I know that class A provides all the methods that I need. How can I go about writing a method that lets me pass either a object C or object D as a parameter?
Am I right in thinking I need to make a generic class? If so does anyone have specific examples that are closer to what I need that this which only seems to tell me how to use the existing collection class?
class A {
public String hello(){return "hello";}
}
class B extends A{}
class C extends B{}
class D extends B{}
The method hello is available in all subclasses B,C and D.
So in E, do something like:
private void test() {
System.out.println(hello(new A()));
System.out.println(hello(new B()));
System.out.println(hello(new C()));
System.out.println(hello(new D()));
}
public String hello(A a) {
return a.hello();
}
and you can pass instances of A,B,C or D
BTW - generics are not necessary in this scenario (as far as I understood it)
If C and D have A as their common ancestror and A provides all needed methods, then your method should simply take an instance of A as a parameter. You do not need a generic method, unless I misunderstood your question.
public void doSomething(A input) {
input.methodInA();
input.secondMethodInA();
...
}
Polymorphism will run an possible overridden code implement in C or D, you don't need to do anything other than call the method.
class A {
}
class B extends A {
}
class C extends B {
}
class D extends B {
}
class E {
public void test ( A a ) {
// c or d will work fine here
}
}