接口是对象的实例,对象是Java中的接口的实例吗?

时间:2019-01-13 18:49:04

标签: java interface

我有一个名为IntF

的接口

我还有一个定义为Cls的类,它实现了IntF

这是一些客户端代码:

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

输出为truetrue

为什么这是输出?我认为应该是falsefalse

我认为i将是IntF的实例,但这没有任何意义,因为您不能真正初始化接口吗?可以吗我对Java很满意,但是这个东西有点模糊。

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

ic都引用了Cls类的实例。因此,两者均为instanceof Cls。而且由于Cls类实现了IntF接口,所以两者都是instanceof IntF

答案 1 :(得分:2)

关键字instanceof在这里具有误导性。 a instanceof B的含义是:

  变量a引用的

对象提供了 class interface B中定义的所有方法,因为{{1 }}(其类)是 class interface a的子孙,通过任何Java继承方式。


  

所以我只能访问IntF接口中定义的方法,而c可以访问Cls类定义的方法?使用instanceof可以告诉B是否可以访问A遵循的任何类或接口中定义的所有方法? –天使加西亚(Angel Garcia)

与其说是“具有访问权限”,不如说是一个问题。由
回答的问题 B是:我可以将对象存储在 a instenceof B(类型为a的变量中(并且 then 访问方法仅在B中可用)。

B

但是
不要花太多的精力来理解if(i instanceof Cls) Cls i2= (Cls)i; 。在现实生活中,您永远都不需要它,因为它可以有效地阻止您使用OOP的最有价值的好处:多态性

答案 2 :(得分:0)

Object.getClass

关于instanceof的其他两个答案是正确的。知道您还可以获得实例的实际具体类可能会澄清您的想法。

Java中的每个类都从Object类扩展而来。 Object包含一个getClass方法。该方法返回Class类型的对象,但不要考虑太多,否则会伤到头部。这里的重点是,您可以随后在您的特定实例后面要求具体类的文本名称。

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

下面是接口Animal和实现该接口的3个类的示例,CatDogChihuahuaChihuahua类将Dog扩展为yip而不是树皮。我们实例化所有3个具体类,但将每个实例都保留为更通用的Animal接口。注意,我们可以获得实例的最具体的子类,例如DogChihuahua

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." ) ;
    }
}

查看此code run live at IdeOne.com.

  

喵。

     

     

树皮。

     

     

是的。

     

奇瓦瓦州


  

我认为我将是IntF的一个实例,但这没有任何意义,因为您不能真正初始化接口吗?或者可以吗?

否,您无法在Java中实例化接口。

但是polymorphism(“许多形状”)的要点是,您可以使用5种方法实例化类中的对象,但是可以像使用对象一样保留对对象的引用,只需使用说3种方法。通过该引用在对象上调用方法时,只能调用3个方法。编译器不允许您调用该类中5个方法中的另外2个,因为从接口的角度来看,这两个方法不存在。我想到了这一点(将对对象的引用作为接口),就像通过滤色镜查看一样,遮挡了某些波长,同时允许其他波长通过。

  

我对Java很满意,但这有点模糊。

别担心,让它变得模糊起来。 实践带来清晰度。抽象地考虑它(双关语意)使这些概念难以掌握。

一旦您处于代码库的某个部分,您想发送一条消息,但是不在乎它是通过电子邮件还是SMS发送出去,那么您将发现拥有Message的智慧与具体类EmailMessageSmsMessage的接口。组成消息的代码部分仅需要接口方法,而实际上按其方式发送消息的代码部分将需要具体的类。

在处理邮件订单履行情况时,如果您收到第一份有特殊需要的国际邮件,例如海关申报单,那么您将需要一个MailOrder接口,其中包含DomesticMailOrder和{ {1}}。您的应用程序列出订单供管理者查看的部分仅需要界面上的方法,例如InternationalMailOrder,而应用程序负责运输的部分则需要具体类提供的不同行为。

另请参阅Wikipedia中的Abstract and concreteClass (computer programming)