类的继承和铸造
因此,我将这段代码放在一个文件夹中,这个文件夹是为了一个项目而停止开发的。但是,对于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
将不知道如何处理它。
你正在看的是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
。但是你可以通过Biz
的execute
方法吗?不,你只能通过String
。所以Biz没有完全满足界面。
[圆椭圆问题] migth是很好的进一步阅读。 1
值得注意的是,签名不一定必须相同;参数类型可能会“松动”。例如,如果接口中的方法接受了'String',则可以让'Biv'中的方法接受'Object'。 – Maxpm 2012-04-08 23:41:34
@Maxpm:事实并非如此。 – Natix 2012-04-08 23:49:29
@natix我站好了。 – Maxpm 2012-04-09 00:32:01