所以我有这个:
interface C {
void shutUp();
}
class A {
public void speak() {
System.out.println("Class a");
}
}
class B extends A implements C {
public void shutUp() {
System.out.println("Saying nothing...");
}
public void speak() {
System.out.println("Class B");
}
}
如果我这样做,它会起作用:
A obj = new B();
obj.speak()
但我做不到obj.shutUp()
为什么不呢?我有一种感觉,我只是对一些非常基本的东西感到困惑。
谢谢!
答案 0 :(得分:2)
A的静态类型未连接到C,因此您无法执行此命令,它将是相同的:
A obj = new A();
obj.shutUp();
(这显然是非法的..)
唯一可以同时使用两者的是B
B obj = new B();
obj.shutUp();
obj.speak();
这与Java static typing
答案 1 :(得分:1)
因为A不是C - 它没有实现接口 - 并且你不能以这种方式实例化接口,因为没有默认的构造函数。
A类型的引用没有方法shutUp()
,所以毫无疑问它不起作用。
您的代码使用了错误的关键字:Java的class
和interface
。案件很重要。
答案 2 :(得分:0)
您的obj
具有来自班级A
的界面,因为它是您变量的类型。
答案 3 :(得分:0)
obj
的类型定义为A
;因此,obj
只能使用A
可用的成员。由于C
继承自A
,C
要求所有成员都被视为A
的形式,这就是为什么它允许您创建新C
在A
变量中。只有将其投放到C
类型,才能使用属于C
的所有成员。
答案 4 :(得分:0)
在你的问题中是错误的:你不能创建C对象因为它的界面 - 所以我认为你想要创建B对象,然后:
这是因为obj是A而不是C,要使用shutUp方法,你可以:
((C) obj).shutUp() // cast to C type
((B) obj).shutUp() // cast to B type
或宣布:
B obj = new B();
obj.shutUp();
或者:
C obj = new B(); // (!) but: you can't (without casting) call speak method
obj.shutUp();
答案 5 :(得分:0)
obj = new C();
由于C是接口,因此无法创建接口实例。请更正问题。
答案 6 :(得分:0)
为什么你不能在obj上调用shutUp的原因是:
obj不是对象,它是指针或引用。你做新B()时创建的对象是一回事,obj(或“你如何使用对象”)是一个单独的东西。您可以在引用的帮助下使用该对象(在本例中为obj),它允许您访问实际对象的不同侧面。
如果用于访问对象的引用属于引用手头对象的类型(即具有相同名称),则可以通过此引用访问整个对象。否则你只能访问引用类型可以看到的对象的那些部分。
在您的示例中,引用类型为A,即obj仅查看其引用的任何对象的A部分。因此,虽然对象具有这些行为,但它无法访问对象的B / C部分。
答案 7 :(得分:0)
其他人已经回复了此问题,但请注意,有一种方法可以在不转发shutUp()
或B
的情况下致电C
:
A obj = new B();
try {
Method shutUp = obj.getClass().getMethod("shutUp", null);
shutUp.invoke(obj, null);
}
catch (Exception ignored) {}
答案 8 :(得分:0)
A obj = new B();
在这里,您要创建“B”的实例,其类型为“A”。 即你说“我想制作一个物体B并将其命名为obj,它是A型”。
在A类中,只有一种方法可以访问。它没有实现C
public void speak() {}
为了能够访问B类的所有方法,你应该创建一个类型为“B”的“B”实例
B obj2 = new B();
这样您就可以访问
public void shutUp() {}
这是因为它是实现类“C”的B。
使用“obj”访问这两种方法的一种方法是制作A工具C
答案 9 :(得分:0)
由new B()
创建的对象可以用作三种类型之一的对象 - A,B或C.但是您不能声明几种类型的变量。
由于B是A和C的子类型,因此您可以将其实例用作任何类型的实例。 E.g。
B o = new B();
A aO = o;
C cO = o;
现在,您可以使用o
访问speak
和shutUp
方法,您可以使用aO
访问speak
方法和cO
访问shutUp
方法。无论你使用哪个变量,调用的方法都是相同的,因为这些变量都引用同一个对象。为什么你不能使用aO
在Java中调用shutUp
是因为你已经使用没有这种方法的类型声明了你的变量。虽然你知道这个特定的对象确实有这种方法一般不会这样做。
class D extends A {
public void speak(){
System.out.println("Class D");
}
}
List<A> as = new ArrayList<A>();
as.add(new A());
as.add(new B());
as.add(new D());
A a0 = as.get(0);
A a1 = as.get(1);
A a2 = as.get(2);
a0.speak(); // >> Class A
a1.speak(); // >> Class B
a2.speak(); // >> Class D
现在,在此示例中,您在单个集合中具有三个不同类的实例。当你传递这个集合或修改它时,你永远不会知道每个对象实际上是哪个类。你所知道的是它们都是A型,它们保证属于那种类型,但实际上它们可以是A的任何子类型(如B或D)。
答案 10 :(得分:0)
通过说A obj = new B();您将代码与特定的接口实现分离。所以obj将无法访问在b类中实现的shutup()函数。