use*_*147 29 java interface abstract
我有这个界面:
public interface Animal {
public void Eat(String name);
}
Run Code Online (Sandbox Code Playgroud)
这段代码实现了这个接口:
public class Dog implements Animal {
public void Eat(String food_name) {
System.out.printf(food_name);
}
public static void main(String args[]) {
Animal baby2 = new Dog(); //HERE!!!!!!!!!!!!!!!!!!!!!!
baby2.Eat("Meat");
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么代码有效?无法实例化接口.然而在这种情况下,界面被实例化(标记为"HERE !!!!!!!!!!!!!").
这里发生了什么?
zw3*_*324 34
不,它不是 - 您正在实例化a Dog,但由于a Dog是a Animal,您可以将变量声明为a Animal.如果您尝试实例化接口Animal,它将是:
Animal baby2 = new Animal();
Run Code Online (Sandbox Code Playgroud)
试试看,并惊恐地看着编译器尖叫:)
Boh*_*ian 20
Dog不是接口:Dog是一类是实现该Animal接口.
这里没有什么不好的事情发生.
请注意,您可以实例化接口的匿名实现,如下所示:
Animal animal = new Animal() {
public void Eat(String food_name) {
System.out.printf("Someone ate " + food_name);
}
};
Run Code Online (Sandbox Code Playgroud)
Set*_*sak 12
我们考虑下面的代码:
interface Cookable {
public void cook();
}
class Food {
Cookable c = new Cookable() {
public void cook() {
System.out.println("anonymous cookable implementer");
}
};
}
Run Code Online (Sandbox Code Playgroud)
上面的代码创建了一个匿名内部类的实例,但是在这里,新的实时类是Cookable接口的实现者.请注意,这是您唯一能看到语法的时间:
new Cookable()
Run Code Online (Sandbox Code Playgroud)
Cookable是一个接口而不是nonabstract类类型.想一想:
你不能实例化一个接口,但这就是它所做的代码.但是,当然,它并没有实例化Cookable object- 它正在创建一个新的实例anonymous implementer of Cookable.
你可以读这一行:
Cookable c = new Cookable(){}
Run Code Online (Sandbox Code Playgroud)
as"声明一个Cookable类型的引用变量,显然,它将引用一个实现Cookable接口的类中的对象.但是,哦,是的,我们还没有一个实现Cookable的类,所以我们要去现在就在这里做一个.我们不需要该类的名称,但它将是一个实现Cookable的类,这个大括号开始新实现类的定义.
重要的是要记住匿名接口实现者 - 他们只能实现一个接口.根本没有任何机制可以说你的匿名内部类将实现多个接口.实际上,匿名内部类甚至无法扩展类并同时实现接口.innve类必须选择要么是命名类的子类,要么根本不直接实现任何接口,要么实现单个接口.
所以不要被实例化接口的任何尝试所欺骗,除非是匿名内部类.以下是不合法的:
Runnable r = new Runnable(); // can't instantiate interface
Run Code Online (Sandbox Code Playgroud)
而以下是合法的,因为它实例化了Runnable接口的实现者(匿名实现类):
Runnable r = new Runnable() {
public void run(){ }
};
Run Code Online (Sandbox Code Playgroud)
你可以在这里阅读我的文章.
您的代码取决于Animal合同的抽象,通过实例化它的具体实现.你只是说,"我正在对某个对象进行即时消息,但无论该对象实际上是什么,它都将受到Animal接口契约的束缚."
举例来说,这些声明:
List<String> wordList = new LinkedList<>();
Map<Integer, String> mapping = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,列表和地图的主要方面是它们遵循a List和的通用合同Map.