简体   繁体   中英

Interfaces are instances of objects and objects are instances of Interfaces in Java?

I have an interface defined called IntF

I also have a Class defined called Cls which implements IntF .

And here is some client code:

IntF i=new Cls();
Cls c=new Cls();
System.out.print(i instanceof Cls);
System.out.print(c instanceof IntF);

the output is truetrue

Why exactly is this the output? I figured it would've been falsefalse .

I thought that i would be an instance of IntF , but that doesn't make sense because you can't really initialize interfaces right? Or can you? I'm comfortable with Java, but this stuff is a little fuzzy.

Any help is appreciated.

Both i and c hold a reference to an instance of the Cls class. Therefore both are instanceof Cls . And since Cls class implements the IntF interface, both are instanceof IntF .

the keyword instanceof is misleading here. The meaning of a instanceof B is:

object referenced to by variable a provides all methods defined in class or interface B because the type of object referenced by a (its class) is a descendant of class or interface B by any means of java inheritance.


So i would only have access to the methods defined in the IntF interface, whereas c would have access to the methods defined the Cls class? And using instanceof just tells whether or not B has access to all methods defined in whatever class or interface A adheres to? – Angel Garcia

It is not so much a question of "having access". The question answered by
a instenceof B is: Can I store the object in a in a variable of type B (and then access methods only available in B ).

if(i instanceof Cls)
   Cls i2= (Cls)i;   

But
Do not invest too much effort in understanding instanceof . You should never need it in real life since it is a tool to effectively prevent you from using the most valuable benefit of OOP: polymorhism .

Object.getClass

The other two Answers are correct about instanceof . It might clarify your thinking to know that you can also obtain the actual concrete class of an instance.

Every class in Java extends from Object class. And Object includes a getClass method. That method returns an object of type Class — but do not think about that too much or it makes your head hurt. The real point here is that you can then ask for the textual name of the concrete class behind your particular instance.

String className = someInstance.getClass().getName() ;

Below is an example of an interface Animal and 3 classes implementing that interface, Cat , Dog , Chihuahua . The Chihuahua class extends Dog to yip instead of bark. We instantiate all 3 concrete classes but hold each instance as the more general Animal interface. Note we can get the most specific subclass of an instance, such as Dog versus Chihuahua .

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Animal animal1 = new Cat() ;
        animal1.speak() ;
        System.out.println( animal1.getClass().getName() ) ;

        Animal animal2 = new Dog() ;
        animal2.speak() ;
        System.out.println( animal2.getClass().getName() ) ;

        Animal animal3 = new Chihuahua() ;
        animal3.speak() ;
        System.out.println( animal3.getClass().getName() ) ;
    }
}

interface Animal {
    public void speak() ;
}

class Dog implements Animal {
    @Override
    public void speak() {
        System.out.println( "Bark." ) ;
    }
}

class Chihuahua extends Dog {
    @Override
    public void speak() {
        System.out.println( "Yip." ) ;
    }
}


class Cat implements Animal {
    @Override
    public void speak() {
        System.out.println( "Meow." ) ;
    }
}

See this code run live at IdeOne.com.

Meow.

Cat

Bark.

Dog

Yip.

Chihuahua


I thought that i would be an instance of IntF, but that doesn't make sense because you can't really initialize interfaces right? Or can you?

No, you cannot instantiate an interface in Java.

But the point of polymorphism (“many shapes”) is that you can instantiate an object from a class with say 5 methods, yet hold a reference to the object as if it were of the interface only, with say 3 methods. When you invoke methods on the object through that reference, you can only invoke the 3 methods. The compiler will not allow you to call the other 2 of the 5 methods on the class, because from the point of view of the interface, those other two methods do not exist. I think of this (holding a reference to an object as a interface) like looking through a color filter lens, blocking out some wavelengths while allowing other wavelengths to pass through.

I'm comfortable with Java, but this stuff is a little fuzzy.

Don't worry, let it be fuzzy. Practice brings clarity . Thinking about it abstractly (pun intended) makes the concepts difficult to grasp.

Once you are in one part of your codebase where you want to send a message but do not care if it goes out by email or SMS , then you will see the wisdom of having a Message interface with concrete classes EmailMessage & SmsMessage . The part of the code composing the message needs only the interface methods, while the part of the code actually sending the message on its way will need the concrete classes.

When you are handling mail order fulfillment, and get your first international mail with special needs such as Customs Declaration, then you will see the need for a MailOrder interface with concrete classes for DomesticMailOrder & InternationalMailOrder . The part of your app listing orders for a manager to view needs only the methods on the interface such as getDollarValue while the part of your app responsible for shipping will need the different behaviors provided by the concrete classes.

See also Wikipedia for Abstract and concrete and Class (computer programming) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM