有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

继承当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 aC c指向相同的对象类型(例如A a = new C();C c = new C();)时,它们之间有什么区别

从这个问题:Java inheritance vs. C# inheritance,看起来像是ac指向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);

    }
}

共 (4) 个答案

  1. # 1 楼答案

    这与变量的运行时类型无关。您可能只知道在编译时根据用户输入有一个Vehicle对象,它可能是GarbageTruckSportsCar

    GarbageTruck t;
    ...
    t = new SportsCar();  //can't do this!
    
    // so we do this:
    Vehicle t;
    if(user.isFast()) {
       t = new SportsCar();
    } else {
       t = new GarbageTruck();
    }
    
  2. # 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. # 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. # 4 楼答案

    Java是关于接口和实现的

    接口只是一组公共字段(方法和属性),描述用户如何与实现接口的类交互

    一个实现是实际上使这些方法和属性起作用的代码。实现可以是implements一个interface的类,也可以是其他实现的子类

    实例化类时,编写的代码如下:

    Interface a = new Implementation();
    

    通常情况下,我们将接口和实现包装在一起。。。换句话说,当我们定义一个class时,无论我们是否显式实现一个接口,我们都是用我们编写的每个public方法定义一个接口

    因此,接口影响我们可以调用什么方法,但实现影响我们调用它们时发生的事情