Let me know if I am wrong but in my experience the instanceof call does not do what I need it to.
I have an abstract class that implements an interface and explicitly overwrites all methods in the interface. I have a subclass of this class. How can I tell if the subclass is an instanceof the interface?
public interface IAnimal {
public void eat();
}
public abstract class Dog implements IAnimal {
#Override
public void eat(){
//eat things
}
public abstract void bark();
}
public class Beagle extends Dog {
#Override
public void bark(){
//specific bark
}
}
So I have an instantiation of Beagle, how do i find out if it is an instance of IAnimal?
You can do a
IAnimal.class.isAssignableFrom(Beagle.class)
or
IAnimal.class.isAssignableFrom(someObjectInstance.getClass());
or even instance of works with interfaces
if (object instanceof IAnimal) { }
Related
I know that multiple inheritances between Interfaces is possible, e.g.:
public interface C extends A,B {...} //Where A, B and C are Interfaces
But is it possible to have a regular Class inherit from multiple Interfaces like this:
public class A implements C,D {...} //Where A is a Class and C and D are interfaces
A Java class can only extend one parent class. Multiple inheritance (extends) is not allowed. Interfaces are not classes, however, and a class can implement more than one interface.
The parent interfaces are declared in a comma-separated list, after the implements keyword.
In conclusion, yes, it is possible to do:
public class A implements C,D {...}
In a word - yes.
Actually, many classes in the JDK implement multiple interfaces. E.g., ArrayList implements List, RandomAccess, Cloneable, and Serializable.
public class A implements C,D {...} valid
this is the way to implement multiple inheritence in java
Yes, a class can implement multiple interfaces. Each interface provides contract for some sort of behavior. I am attaching a detailed class diagram and shell interfaces and classes.
Ceremonial example:
public interface Mammal {
void move();
boolean possessIntelligence();
}
public interface Animal extends Mammal {
void liveInJungle();
}
public interface Human extends Mammal, TwoLeggedMammal, Omnivore, Hunter {
void liveInCivilization();
}
public interface Carnivore {
void eatMeat();
}
public interface Herbivore {
void eatPlant();
}
public interface Omnivore extends Carnivore, Herbivore {
void eatBothMeatAndPlant();
}
public interface FourLeggedMammal {
void moveWithFourLegs();
}
public interface TwoLeggedMammal {
void moveWithTwoLegs();
}
public interface Hunter {
void huntForFood();
}
public class Kangaroo implements Animal, Herbivore, TwoLeggedMammal {
#Override
public void liveInJungle() {
System.out.println("I live in Outback country");
}
#Override
public void move() {
moveWithTwoLegs();
}
#Override
public void moveWithTwoLegs() {
System.out.println("I like to jump");
}
#Override
public void eat() {
eatPlant();
}
#Override
public void eatPlant() {
System.out.println("I like this grass");
}
#Override
public boolean possessIntelligence() {
return false;
}
}
public class Lion implements Animal, FourLeggedMammal, Hunter, Carnivore {
#Override
public void liveInJungle() {
System.out.println("I am king of the jungle!");
}
#Override
public void move() {
moveWithFourLegs();
}
#Override
public void moveWithFourLegs() {
System.out.println("I like to run sometimes.");
}
#Override
public void eat() {
eatMeat();
}
#Override
public void eatMeat() {
System.out.println("I like deer meat");
}
#Override
public boolean possessIntelligence() {
return false;
}
#Override
public void huntForFood() {
System.out.println("My females hunt often");
}
}
public class Teacher implements Human {
#Override
public void liveInCivilization() {
System.out.println("I live in an apartment");
}
#Override
public void moveWithTwoLegs() {
System.out.println("I wear shoes and walk with two legs one in front of the other");
}
#Override
public void move() {
moveWithTwoLegs();
}
#Override
public boolean possessIntelligence() {
return true;
}
#Override
public void huntForFood() {
System.out.println("My ancestors used to but now I mostly rely on cattle");
}
#Override
public void eat() {
eatBothMeatAndPlant();
}
#Override
public void eatBothMeatAndPlant() {
eatPlant();
eatMeat();
}
#Override
public void eatMeat() {
System.out.println("I like this bacon");
}
#Override
public void eatPlant() {
System.out.println("I like this broccoli");
}
}
Of course... Almost all classes implements several interfaces. On any page of java documentation on Oracle you have a subsection named "All implemented interfaces".
Here an example of the Date class.
It is true that a java class can implement multiple interfaces at the same time, but there is a catch here.
If in a class, you are trying to implement two java interfaces, which contains methods with same signature but diffrent return type, in that case you will get compilation error.
interface One
{
int m1();
}
interface Two
{
float m1();
}
public class MyClass implements One, Two{
int m1() {}
float m1() {}
public static void main(String... args) {
}
}
output :
prog.java:14: error: method m1() is already defined in class MyClass
public float m1() {}
^
prog.java:11: error: MyClass is not abstract and does not override abstract method m1() in Two
public class MyClass implements One, Two{
^
prog.java:13: error: m1() in MyClass cannot implement m1() in Two
public int m1() {}
^
return type int is not compatible with float
3 errors
Yes, it is possible. This is the catch: java does not support multiple inheritance, i.e. class cannot extend more than one class. However class can implement multiple interfaces.
An interface can extend other interfaces. Also an interface cannot implement any other interface.
When it comes to a class, it can extend one other class and implement any number of interfaces.
class A extends B implements C,D{...}
For my Java class, we are learning about interfaces, polymorphism, inheritance, etc.
The homework assignment I am working on is a memory game where you have pairs of cards all face down and you turn over two at a time looking for a match. If they match, they stay visible, if they don't, the cards are turned back over and you pick two more cards.
My design so far is as follows:
public interface Hideable
public abstract void hide();
public abstract void show();
public interface Speakable
public abstract String speak();
public interface AnimalCard extends Hideable, Speakable
public abstract boolean equals(Object obj);
public class Animal implements AnimalCard
public void hide() { ... }
public void show() { ... }
public boolean equals(Object obj) { ... }
// What do I do for the speak method since a generic Animal
// can't speak, but I have to provide a definition since the
// Animal class is implementing the interfaces.
public class Puppy extends Animal
// Here is where I need to define the speak method.
public String speak() { ... }
My question is in the comments above. I feel like I'm implementing this incorrectly with regard to the speak() method.
Just make the Animal class abstract.
Concrete classes will have to implement speak(), or be abstract themselves.
public class abstract Animal implements AnimalCard {
public void hide() { ... }
public void show() { ... }
public boolean equals(Object obj) { ... }
There's no need or value in declaring an abstract method for speak() in Animal - that method is implied by the class hierarchy.
the purpose of an interface is to guarantee that your class will behave in a certain way.
So if you declare a speakable object
Speakable speakingThing = new Puppy();
Whatever you put in that speakableThing variable must be able to do anything that the Speakable interfaces says it can do.
What I'd do, is not have AnimalCard implement Speakable and have only Animals that can speak implement the interface
Or, as other people said, if All your animals will speak, and you just will never instantiate the generic animal, than make your classes abstract.(abstract classes don't get instantiated. they're only there to be inherited from. )
you could make this kind of change
public abstract class Animal implements AnimalCard{
public void hide() { }
public void show() { }
public abstract String speak();
}
First,
you cant have abstract methods in an interface. They are essentially abstract by default, since it is illegal to have any implementation code within the interface.
Second, java doesnt support multiple inheritance, so your line:
public interface AnimalCard extends Hideable, Speakable
is illegal.
The best way to solve your problem once you fix those things is to make Animal card abstract.
public abstract Animal extends AnimalCard {
public void hide() { ... }
public void show() { ... }
public boolean equals(Object obj) { ... }
public abstract String speak();
}
public class Puppy extends Animal {
// Here is where I need to define the speak method.
public String speak() { ... }
}
We have a Class(say Animal), and we have an Interface(say Behave). Both Animal as well as Behave have a method with the same signature(say public void eat()).
When we try to write the body for the method eat() in a Class(say Dog) which extends Animal and implements Behave, which eat() method is actually referred to? The one in Animal or Behave. In whichever case that happens, why does it happen that way?
Edit:
I tried this scenario on Eclipse before posting this question.
An interesting part here is, even though I am implementing Behave, if I dont create an eat() method(i.e. if I dont implement Behave's inherited abstract method) inside Dog, there is no error, since I am already extending from Animal which has an eat() method.
which eat() method is actually referred to? BOTH.
Try this: if you don't override the method at all, when you call with the interface, you will get the one from the parent.
Behave b = new Dog();
System.out.println(b.eat());//this will call eat from Animal if Dog did not override.
If you override, you always get the one from the child:
Behavior b = new Dog();
Animal a = new Dog();
a.eat() and b.eat() will both refer to the eat inside of Dog class.
USE THESE CLASSES:
public class BClass {
public int add(int a, int b){
return a*b;
}
}
public interface BInterface {
public int add(int a, int b);
}
public class BChild extends BClass implements BInterface{
public static void main(String... args){
BInterface bi = new BChild();
BClass bc = new BChild();
System.out.println(bi.add(3, 5));
System.out.println(bi.add(3, 5));
}
#Override
public int add(int a, int b){
return a+b;
}
}
interface can contain only body definition of method , once you implements, it must have implementation of all defined methods. In you example
class Dog extends Animal implements Behave
{
#Override
public void eat() {...}
}
abstract class Animal{
public abstract void eat();
}
interface Behave{
void eat();
}
Here it need a body of abstract method where as it is in Main method. In other way
class DOG extends Animal implements Behave{
...
}
class Animal{
public void eat(){
...
}
}
interface Behave{
void eat();
}
Here Dog class having eat method body in its super class Animal. So it wount ask to implement body again in Animal as it is already implemented.
An interface simply defines a method that a class must provide. If we have
public class Animal{
public void eat(){
System.out.println("Om nom nom");
}
}
public class Dog extends Animal{
}
Dog now provides the eat method and can so implement Behave.
There is only one eat() method, because the designers of the language decided that the simplicity of having the method signature consist of its name and argument types was more useful than having the complexity of being able to specify that you are providing an implementation of an interface.
In Java, if the two have different semantics, provide a method which returns a Behave instance which does something else:
class Animal {
public void eat () { }
}
interface Behave {
void eat ();
}
class Dog extends Animal {
public void eat () {
// override of Animal.eat()
}
public Behave getBehave() {
return new Behave {
public void eat() {
BehaveEat();
}
};
}
private void BehaveEat() {
// effectively the implementation Behave.eat()
}
}
In other languages, you can explicitly state that a method implements a method from an interface.
I have the following interface:
public interface SingleRecordInterface<T> {
public void insert(T object);
}
I have the abstract class below (that does not mention the method insert):
public abstract class AbstractEntry implements SingleRecordInterface<AbstractEntryBean> {
}
I have the concrete class:
public class SpecificEntry extends AbstractEntry {
public void insert(SpecificEntryBean entry) {
// stuff
}
}
Finally, SpecificEntryBean is defined as:
public class SpecificEntryBean extends AbstractEntryBean {
}
I have the following error:
The type SpecificEntry must implement the inherited abstract method SingleRecordInterface.insert(AbstractEntryBean)
I don't understand the reason for this error, given that SpecificEntryBean extends AbstractEntryBean. How do I fix this error?
You need to make your abstract class generic as well:
public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}
Then for your concrete class:
public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
}
Change to the following:
public abstract class AbstractEntry<EB extends AbstractEntryBean> implements SingleRecordInterface<EB> {
}
and
public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
public void insert(SpecificEntryBean entry) {
// stuff
}
}
The problem is in your declaration of
public abstract class AbstractEntry implements SingleRecordInterface<AbstractEntryBean> {}
This is the place where you define what is type argument (AbstracEntryBean) for the type parameter T.
Therefore, T is AbstracEntryBean, and when you intend to override this method to finally implement it you are required to provide the exact method signature for the method. In this case:
#Override
public void insert(AbstractEntryBean object) {
// TODO Auto-generated method stub
}
Since Java requires the exact same method signature to override a given method.
You can either provide a type parameter for your class, as others have suggested, or provide a bridge (overloading) method as follows:
//overloading
public void insert(SpecificBean object){
insert((AbstractEntryBean) object);
}
public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}
public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
public void insert(SpecificEntryBean entry) {
// stuff
}
}
Of course, the following doesn't work in Java (no abstract static methods)...
public abstract class Animal {
public abstract static Animal getInstance(byte[] b);
}
public class Dog extends Animal {
#Override
public static Dog getInstance(byte[] b) {
// Woof.
return new Dog(...);
}
}
public class Cat extends Animal {
#Override
public static Cat getInstance(byte[] b) {
// Meow.
return new Cat(...);
}
}
What's the correct way of requiring that Animal classes have a static getInstance method that instantiates itself? This method should be static; a "normal" abstract method doesn't make sense here.
There is no way to specify in an abstract class (or interface) that an implementing class must have a particular static method.
It is possible to get a similar effect using reflection.
One alternative is to define an AnimalFactory interface separate from the Animal class:
public interface AnimalFactory {
Animal getInstance(byte[] b);
}
public class DogFactory implements AnimalFactory {
public Dog getInstance(byte[] b) {
return new Dog(...);
}
}
public interface Animal {
// ...
}
class Dog implements Animal {
// ...
}