类的继承和铸造

问题描述:

因此,我将这段代码放在一个文件夹中,这个文件夹是为了一个项目而停止开发的。但是,对于Java而言,我有几个问题(并且我知道代码不能编译,但这成为我的一个问题)。类的继承和铸造

interface Executable { 
    public int execute (Object o); 
} 

public class Biv implements Executable { 

    public int execute (String s) { 
    System.out.println (s); 
    return s.length(); 
    } 

    public static void main (String[] args) { 
    Executable e = new Biv(); 
    System.out.println( 
     e.execute ("Hello World!")); 
    } 


} 

1)我的第一个问题是与变量e做。它是用可执行对象类型声明的,但我不明白为什么可以用新的Biv对象实例化。这里发生了什么,这是什么意思?

2)错误发生在Biv类的execute方法中。这似乎是因为它期望一个对象而不是一个字符串。然而,你能不能用一个字符串替换一个对象,因为字符串是对象的一个​​子类?我可以理解,如果你用Object替换了String,它会有一个错误(我认为),但不是它目前如何完成。

I don't understand why it can then be instantiated with a new Biv object

由于Biv器具Executable,所以Biv任何实例也是Executable一个实例。

The error is in the execute method within the Biv class

是的,它[Biv]没有实现execute(Object)。方法execute(String)仅仅是碰巧具有相同名称的不同方法,因为它们不具有相同的签名。任何实现接口Executable的类都必须覆盖方法execute(Object)

在java中没有用于覆盖方法的参数co-variance,因为它是不安全的。如果你调用e.execute(new Object())会怎么样? [其中e引用Biv对象] Biv将不知道如何处理它。

+1

值得注意的是,签名不一定必须相同;参数类型可能会“松动”。例如,如果接口中的方法接受了'String',则可以让'Biv'中的方法接受'Object'。 – Maxpm 2012-04-08 23:41:34

+0

@Maxpm:事实并非如此。 – Natix 2012-04-08 23:49:29

+0

@natix我站好了。 – Maxpm 2012-04-09 00:32:01

你正在看的是Polymorphism,这是面向对象程序的基本概念之一。要回答您的具体问题#2,您需要匹配接口中的方法的类型签名(它将一个对象作为参数),然后将其转换为字符串。这(铸造)在Java中是bad practice,但应尽可能避免。

你是不是覆盖Executable方法(这是必需的),你是超载它(名称相同,不同的参数类型)。

使用@Override注释,这将有助于突出错误:

public class Biv implements Executable { 

    @Override // This will cause an error to be highlighted saying this isn't overriding any method 
    public int execute (String s) { 
    System.out.println (s); 
    return s.length(); 
    } 
} 

1)变量e被声明为一个可执行文件,是起搏实现接口。这意味着您可以实例化一个Biv,但将其存储为可执行文件并将其作为可执行文件传递。该变量现在只能被视为可执行文件。这是多态性。

2)这是因为你试图覆盖一个函数并添加额外的签名限制。这违反了Liskov替代原则。对于职能,这个原则基本上规定你应该“承诺不多,不需要更多”。你所做的是通过强制参数成为一个字符串“需要更多”,当接口说它可以是一个对象。然后,将它与(1)联系起来,如果你的main中的Executable对象调用了它的execute()方法,它不应该限制你只传递一个String(因为Executable接口说execute()可以接受一个Object )。

Object类实现了toString()方法,因此不需要转换。改变起搏接收对象,而不是字符串,并以该方法首先调用该对象的toString(),然后获取字符串的长度:

interface Executable { 
    public int execute (Object o); 
} 

public class Biv implements Executable { 

    public int execute (Object s) { 
     System.out.println (s); 
     return s.toString().length(); 
    } 

    public static void main (String[] args) { 
     Executable e = new Biv(); 
     System.out.println( 
      e.execute ("Hello World!")); 
    } 

} 

然而,这是一般不好的做法,实行命令设计模式与对象为了有一个方法接受几种类型的可能参数。最好将参数封装在Parameter接口后面。

首先让我们来看看这条线:

public class Biv implements Executable

implements Executable表明类Biv可以采取Executable的作用。或者换句话说,Biv具有Executable中所有方法的实现。

这就解释了为什么后来你可以这样做:

Executable e = new Biv();

Executable类型的变量,并在此之际,我将使用Biv实现这一点。如果Biv实现Executable接口(并声明它在你的例子中有),那么这是可以的。

现在让我们来看看这个例子中出现问题的地方。在可执行的接口包括这种方法declartion:

public int execute (Object o);

这上面说,你可以叫execute,并通过在你喜欢的任何绝对Object。但是你可以通过Bizexecute方法吗?不,你只能通过String。所以Biz没有完全满足界面。

[圆椭圆问题] migth是很好的进一步阅读。 1