我有一个名为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很满意,但是这个东西有点模糊。
感谢您的帮助。
答案 0 :(得分:4)
i
和c
都引用了Cls
类的实例。因此,两者均为instanceof Cls
。而且由于Cls
类实现了IntF
接口,所以两者都是instanceof IntF
。
答案 1 :(得分:2)
关键字instanceof
在这里具有误导性。 a instanceof B
的含义是:
变量a
引用的对象提供了 class 或 interface
B
中定义的所有方法,因为{{1 }}(其类)是 class 或 interfacea
的子孙,通过任何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个类的示例,Cat
,Dog
,Chihuahua
。 Chihuahua
类将Dog
扩展为yip而不是树皮。我们实例化所有3个具体类,但将每个实例都保留为更通用的Animal
接口。注意,我们可以获得实例的最具体的子类,例如Dog
与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." ) ;
}
}
查看此code run live at IdeOne.com.
喵。
猫
树皮。
狗
是的。
奇瓦瓦州
我认为我将是IntF的一个实例,但这没有任何意义,因为您不能真正初始化接口吗?或者可以吗?
否,您无法在Java中实例化接口。
但是polymorphism(“许多形状”)的要点是,您可以使用5种方法实例化类中的对象,但是可以像使用对象一样保留对对象的引用,只需使用说3种方法。通过该引用在对象上调用方法时,只能调用3个方法。编译器不允许您调用该类中5个方法中的另外2个,因为从接口的角度来看,这两个方法不存在。我想到了这一点(将对对象的引用作为接口),就像通过滤色镜查看一样,遮挡了某些波长,同时允许其他波长通过。
我对Java很满意,但这有点模糊。
别担心,让它变得模糊起来。 实践带来清晰度。抽象地考虑它(双关语意)使这些概念难以掌握。
一旦您处于代码库的某个部分,您想发送一条消息,但是不在乎它是通过电子邮件还是SMS发送出去,那么您将发现拥有Message
的智慧与具体类EmailMessage
和SmsMessage
的接口。组成消息的代码部分仅需要接口方法,而实际上按其方式发送消息的代码部分将需要具体的类。
在处理邮件订单履行情况时,如果您收到第一份有特殊需要的国际邮件,例如海关申报单,那么您将需要一个MailOrder
接口,其中包含DomesticMailOrder
和{ {1}}。您的应用程序列出订单供管理者查看的部分仅需要界面上的方法,例如InternationalMailOrder
,而应用程序负责运输的部分则需要具体类提供的不同行为。
另请参阅Wikipedia中的Abstract and concrete和Class (computer programming)。