继承当C是Java中A的子类时,“C=new C()”和“A C=new C()”之间的区别
假设我们将类A作为父类,而类C扩展了它
class A
{
void m()
{
System.out.println("A.m");
}
}
class C extends A
{
@Override
void m()
{
System.out.println("C.m");
}
}
当我们使用引用A a
和C c
指向相同的对象类型(例如A a = new C();
和C c = new C();
)时,它们之间有什么区别
从这个问题:Java inheritance vs. C# inheritance,看起来像是a
和c
指向C的对象类型,使用它们似乎没有区别
我测试了这段代码,它们都打印了C.m
class inherit {
void x(A a)
{
a.m();
}
public static void main(String[] args) {
System.out.println("hello");
A a = new C();
C c = new C();
a.m();
c.m();
new inherit().x(a);
new inherit().x(c);
}
}
# 1 楼答案
这与变量的运行时类型无关。您可能只知道在编译时根据用户输入有一个
Vehicle
对象,它可能是GarbageTruck
或SportsCar
# 2 楼答案
这取决于对象的用途
如果您实际需要的对象具有
A
的接口(即A
的类型),强烈建议使用A a = new C();
。这样就清楚地表明,您想要的是A
接口,而不是C
实现。稍后当您改变主意时,您可以安全地将其更改为A a = new Another_Subtype_Of_A();
,而无需中断其他代码当
A
是一个接口(在您的例子中,A
是一个类)时,尤其如此。例如,如果您只想要一个列表,List list = new ArrayList();
显然比ArrayList list = new ArrayList();
好。这叫做“编程到接口,而不是实现”如果您创建的对象特别需要
C
的接口(特别是A
中不存在的接口),最好选择C c = new C();
。如果您改为编写A a = new C()
,那么迟早还是要将对象强制转换为C
(因为A没有您想要的所有接口),那么为什么还要麻烦呢# 3 楼答案
首先
A
是父类C
是子类,当您执行A a = new A()
操作时,A
的对象被A
句柄创建并保持。当您执行C c = new C()
操作时,C
的对象正在创建,并且C
句柄将保存它。。但当您执行A a = new C()
操作时,将创建C
的对象,并且A
句柄将保存它。这意味着C
的所有属性现在都已被使用。尽管A
的句柄由C
的属性(实例)使用。这是美国的多态性。现在它将使用C的所有重载方法,而不是A的重载方法用作示例
当您创建一个大型项目并为子类创建方法时,就会出现这种差异
假设您有
hello
方法public void hello(C c) { }
将来你会有另一个B类,它扩展了A。。在这种情况下,不能使用
hello
,因为它的参数类型是C。。想象一下,作为一个类的子类,有许多类需要使用这样的方法(那么您将创建多少这样的方法)。多态性是解救之道使用as参数创建hello
public void hello (A x) { }
现在您可以对
A
的所有子级使用相同的方法A c = new C()
A b = new B()
现在所有人都可以使用
hello
这就是多态性的美# 4 楼答案
Java是关于接口和实现的
接口只是一组公共字段(方法和属性),描述用户如何与实现接口的类交互
一个实现是实际上使这些方法和属性起作用的代码。实现可以是
implements
一个interface
的类,也可以是其他实现的子类实例化类时,编写的代码如下:
通常情况下,我们将接口和实现包装在一起。。。换句话说,当我们定义一个
class
时,无论我们是否显式实现一个接口,我们都是用我们编写的每个public
方法定义一个接口因此,接口影响我们可以调用什么方法,但实现影响我们调用它们时发生的事情